PYO Certificates

Posted by on May 5, 2012 in Blog, Web Development | No Comments
PYO Certificates

A BYO Barbie is not the latest incarnation of a Mattel product, it’s a “Bring-Your-Own Barbeque”, Australia’s excuse for a convenient cheap get-together — what  South Africans call a “Bring-‘n-Braai”. BYOD is the latest buzz in mobility – Bring Your Own Data.

PYO (Print-Your-Own) Certificates came about as a Potion solution for a convenient way for SAVRALA to issue membership certificates to its paid-up members.

The Brief: “We want our paid up members to print their own membership certificates from the website”.   That’s it.

The Scope: Expand user profiles to include membership fields, like paid-up status, company name, etc.  Create a page on the website that is available to logged in users, which, when visited, triggers a validation process to check if the user is entitled to a certificate.  Pass the validated information securely to the certificate generator, which reads the information and generates a PDF that automatically downloads.  Easy.

Adding Fields to Member Profiles

We decided to use a WordPress plugin for this — Marco Cimmino’s  Cimy User Extra Fields plugin — and used this to add fields:  Company Name, Membership Number,  Membership Year  and  Paid-Up Status.  These fields can be changed by the membership administrator only.

The PYO certificate input preparation

As previously stated, the SAVRALA website is built on WordPress, using a theme written by Potion.  We decided to create some WordPress shortcodes to execute our certificate input preparation code.  In our theme’s function.php we added the following:

function member_certificate_shortcode ( $atts, $content = null ) {
    $content = "Checking Member Status...<br /><br />";
    if ( !is_user_logged_in() ) {
        $content .= "<span style=\"color:red;font-weight:bold;\">Χ   </span>User not logged in.<br /><br />";
        $content .= "Please <a href=\"\">log in</a> and try again.<br />";
    } else {
        $user_ID   = get_current_user_id();
        $user_info = get_userdata($user_ID);

        // get the CIMY extended fields
        $company_name      = get_cimyFieldValue($user_ID, "COMPANY_NAME");
        $membership_number = get_cimyFieldValue($user_ID, "MEMBERSHIP_NUMBER");
        $membership_year   = get_cimyFieldValue($user_ID, "MEMBERSHIP_YEAR");
        $paid_up           = get_cimyFieldValue($user_ID, "PAID_UP");
        $checksum          = md5(date('z')."$cert_secret");

        $content .= "<span style=\"color:green\">✔   </span>Company Name: ".$company_name."<br \>";
        $content .= "<span style=\"color:green\">✔   </span>SAVRALA Membership Number: ".$membership_number."<br />";
        $content .= "<span style=\"color:green\">✔   </span>Latest Membership Period: ".$membership_year."<br />";

        if (($paid_up == "NO") || ($paid_up == null)) {
            $content .= "<span style=\"color:red\">Χ   </span>Membership Status: Not activated for current period.<br /><br />";
            $content .= "Please <a href=\"\">contact SAVRALA</a> to renew or activate your membership.<br />";
        } else {
            $content .= "<span style=\"color:green\">✔   </span>Membership Status: OK - Paid-up for current period.<br /><br />";
            $content .= "Requesting Certificate with checksum: ".$checksum."...<br /><br />";
            $content .= "<a href=\"";
            $content .= "?y=".$membership_year;
            $content .= "&c=".$company_name;
            $content .= "&n=".$membership_number;
            $content .= "&s=".$checksum;
            $content .= "\">Click here to download your Membership Certificate</a><br />" ;
    return $content;
add_shortcode('certificate', 'member_certificate_shortcode');

To use the shortcodes is simple.  In the WordPress Post or Page content:


On the front-end, if everything worked, the user would be presented with a link “Click here to download your membership certificate”, which, if clicked, will activate the Certificate Generator using the validated fields and a checksum.

The Certificate Generator

As you may have noticed, the Certicate Generator has a sub-domain all to itself.  This is not strictly necessary, but its quite elegant and helps me avoid screwing up the .htaccess file.  The generator uses the excellent TCPDF library to generate the PDF output file.  Here’s the code:

/* Auto Generate PDF of Members Certificate using TCPDF -
 * Usage:  print.php?c=co-name&amp;y=[year]&amp;n=[member#]&amp;s=[checksum]
$year    = $_GET["y"];
$company = $_GET["c"];
$number  = $_GET["n"];
$sum     = $_GET["s"];
$check   = md5(date('z')."$this-bit-is-a-secret");

if ($check != $sum) {
    header("Location:"); //redirect


// create new PDF document
$pdf = new TCPDF("L", PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);

// set document information
$pdf-&gt;SetAuthor('SAVRALA Admin');
$pdf-&gt;SetTitle('SAVRALA Membership Certificate');
$pdf-&gt;SetSubject('Printable PDF');
$pdf-&gt;SetKeywords('SAVRALA, membership, certificate');

//  remove default header/footer

// set default monospaced font

//set margins
$pdf-&gt;SetMargins(30, PDF_MARGIN_TOP, 30);

//set auto page breaks
$pdf-&gt;SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);

//set image scale factor

//set some language-dependent strings

// ---------------------------------------------------------
// add a page
$pdf-&gt;SetAutoPageBreak    (false, 0);

// Draw the nested outer boxes
$linestyle=array('width' =&gt; 1.5, 'cap' =&gt; 'butt', 'join' =&gt; 'miter', 'dash' =&gt; 0, 'color' =&gt; array(185, 188, 223));
$pdf-&gt;Polygon($points,'DF',array('all' =&gt; $linestyle),$fillcolor,true);

$linestyle=array('width' =&gt; 1.5, 'cap' =&gt; 'butt', 'join' =&gt; 'miter', 'dash' =&gt; 0, 'color' =&gt; array(185, 188, 223));

// place the SAVRALA logo image
$pdf-&gt;Image('images/logo.jpg', 15, 20, 40, '', 'JPG', '', '', true, 300, 'C', false, false, 0, false, false, false);

// place the SAVRALA background image
$pdf-&gt;Image('images/background.jpg', '', 146, 273, '', 'JPG', '', 'B', true, 300, 'C', false, false, 0, true, false, false);

// place the signature
$pdf-&gt;Image('images/signature.png', 198, 138, 50, '', 'PNG', '', '', true, 300, '', false, false, 0, false, false, false);

// print a blocks of text using Write()
$pdf-&gt;SetFont('gothic', 'B', 24);
$pdf-&gt;Write($h=0, $txt, $link='', $fill=0, $align='C', $ln=true, $stretch=0, $firstline=false, $firstblock=false, $maxh=0);

$pdf-&gt;SetFont('gothic', '', 22);
$pdf-&gt;SetTextColor(185, 188, 223);
$txt="Proud member of the";
$pdf-&gt;Write($h=0, $txt, $link='', $fill=0, $align='C', $ln=true, $stretch=0, $firstline=false, $firstblock=false, $maxh=0);

$txt="Southern African Vehicle Rental and Leasing Association";
$pdf-&gt;Write($h=0, $txt, $link='', $fill=0, $align='C', $ln=true, $stretch=0, $firstline=false, $firstblock=false, $maxh=0);

$pdf-&gt;SetFont('gothicb', 'B', 28);
$pdf-&gt;Write($h=0, $txt, $link='', $fill=0, $align='C', $ln=true, $stretch=0, $firstline=false, $firstblock=false, $maxh=0);

$pdf-&gt;SetFont('gothic', '', 16);
$pdf-&gt;Write($h=0, $txt, $link='', $fill=0, $align='C', $ln=true, $stretch=0, $firstline=false, $firstblock=false, $maxh=0);

$pdf-&gt;SetFont('gothic', '', 12);
$txt="Membership Number: " . $number;
$pdf-&gt;Write($h=0, $txt, $link='', $fill=0, $align='L', $ln=true, $stretch=0, $firstline=false, $firstblock=false, $maxh=0);

$pdf-&gt;SetFont('gothic', '', 6);
$txt="Verification of membership must always be confirmed\n"."with the members listing on the SAVRALA website.";
$pdf-&gt;Write($h=0, $txt, $link='', $fill=0, $align='L', $ln=true, $stretch=0, $firstline=false, $firstblock=false, $maxh=0);

$pdf-&gt;SetFont('gothic', '', 12);
$txt="Wayne Duvenage, SAVRALA President";
$pdf-&gt;Write($h=0, $txt, $link='', $fill=0, $align='R', $ln=true, $stretch=0, $firstline=false, $firstblock=false, $maxh=0);

// ---------------------------------------------------------
//Close and output PDF document.  Options: 'I' = show in browser, 'D' = download
$outfilename = "SAVRALA-".$year.".pdf";
$pdf-&gt;Output($outfilename, 'D');
// $pdf-&gt;Output($outfilename, 'I');

And that’s it!