CakePHP Setup and Configuration
Configure for Use
  • Edit [cakephp]/app/Config/core.php and modify the following:
    // A random string used in security hashing methods.
    Configure::write('Security.salt', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');
    // A random numeric string (digits only) used to encrypt/decrypt strings.
    Configure::write('Security.cipherSeed', '76859309657453542496749683645');
  • For system-wide user-defined variables, edit [cakephp]/app/Config/core.php and add the following:
    /**
     //#######################################################
     //# User-defined system strings.
     //#######################################################
     Configure::write('Company.Name', 'Acme Inc.');       // Company Name
     Configure::write('Company.Email', 'info@acme.com');  // Company Email

Read a config variable using:

  Configure::read('Company.Name')
Database Configuration

Edit file [cakephp]/app/Config/database.php:

public $default = array(
    'datasource' => 'Database/Mysql',
    'persistent' => false,
    'host' => 'localhost',
    'port' => '',
    'login' => 'acmeusr',
    'password' => 'c4k3-rUl3Z',
    'database' => 'acme_cakephp_db',
    'schema' => '',
    'prefix' => '',
    'encoding' => 'utf8'
);
Email Configuration

Edit file [cakephp]/app/Config/email.php:

class EmailConfig {
 
    public $default = array(
        'transport' => 'Mail',
        //'from'    => Configure::read('Company.Email'),
        'from'      => 'info@acme.com', 
        'charset'   => 'utf-8',
        'headerCharset' => 'utf-8',
    );
 
    public $smtp = array(
        'transport'  => 'Smtp',
        //'from'     => array('site@localhost' => 'My Site'),
        //'from'     => array(Configure::read('Company.Email') => Configure::read('Company.Name')),
        'from'       => array('info@acme.com' => 'Acme Inc'),
        'host'       => 'localhost',
        'port'       => 25,
        'timeout'    => 30,
        //'username' => 'user',
        //'password' => 'secret',
        'username'   => null,
        'password'   => null,
        'client'     => null,
        'log'        => false,
        'charset'    => 'utf-8',
        'headerCharset' => 'utf-8',
    );
 
    public $fast = array(
        //'from'      => 'you@localhost',
        //'from'      => Configure::read('Company.Email'),
        'from'        => 'info@acme.com', 
        'sender'      => null,
        'to'          => null,
        'cc'          => null,
        'bcc'         => null,
        'replyTo'     => null,
        'readReceipt' => null,
        'returnPath'  => null,
        'messageId'   => true,
        'subject'     => null,
        'message'     => null,
        'headers'     => null,
        'viewRender'  => null,
        'template'    => false,
        'layout'      => false,
        'viewVars'    => null,
        'attachments' => null,
        'emailFormat' => null,
        'transport'   => 'Smtp',
        'host'        => 'localhost',
        'port'        => 25,
        'timeout'     => 30,
        //'username'  => 'user',
        //'password'  => 'secret',
        'username'    => null,
        'password'    => null,
        'client'      => null,
        'log'         => true,
        'charset'     => 'utf-8',
        'headerCharset' => 'utf-8',
    );
 
    /*
    // To use this feature, you will need to have the SSL configured in your PHP install.
    public $gmail = array(
        'host'      => 'ssl://smtp.gmail.com',
        'port'      => 465,
        'username'  => 'my@gmail.com',
        'password'  => 'secret',
        'transport' => 'Smtp'
    );
    // or using TLS SMTP
    public $gmail = array(
        'host'      => 'smtp.gmail.com',
        'port'      => 465,
        'username'  => 'my@gmail.com',
        'password'  => 'secret',
        'transport' => 'Smtp',
        'tls'       => true
    );
    */
 
}
Setup AppController

Edit file [cakephp]/app/Controller/AppController.php:

App::uses('Controller', 'Controller');
App::uses('SessionComponent', 'Controller/Component');
App::uses('SessionHelper', 'Controller/Component'); 
App::uses('AuthHelper ', 'Controller/Component'); 
 
class AppController extends Controller 
{
    public $components = array(
        'Session',
        'Auth' => array(
            //'loginRedirect' => array('controller' => 'articles', 'action' => 'index'),  // at login, go to Articles list
            'loginRedirect'  => array('controller' => 'pages', 'action' => 'display', 'home'),  // at login, go to Home
            //'logoutRedirect' => array('controller' => 'users', 'action' => 'login'),
            'logoutRedirect' => array('controller' => 'pages', 'action' => 'display', 'home'),  // at logout, go to Home
            'authError'      => 'You must be logged in to view this page.',
            'loginError'     => 'Invalid Username or Password entered, please try again.',
            'authorize' => array('Controller')
        ),
        'DebugKit.Toolbar',    // see https://github.com/cakephp/debug_kit for more details
    );
 
    // only allow the login controllers only
    public function beforeFilter() 
    {
        $this->Auth->allow('login');
    }
 
    public function isAuthorized($user) 
    {
        // Here is where we should verify the role and give access based on role
        //return true;
 
        // Admin can access every action
        if (isset($user['role']) && $user['role'] === 'admin') 
        {
            return true;
        }
 
        // Default deny
        return false;
    }
}
Setup UserController

Edit file [cakephp]/app/Config/routes.php to include custome routes:

// ###--- Custom Routes ---###    
// Let us modify the core components of CakePHP to support the UserController login module. 
// First, we need to modify routes.php so that we can have a custom link for login, logout 
// and the dashboard. This step is not required but I do it so that the URLs look clean.
Router::connect('/dashboard', array('controller' => 'users', 'action' => 'index'));
Router::connect('/login',     array('controller' => 'users', 'action' => 'login'));
Router::connect('/logout',    array('controller' => 'users', 'action' => 'logout'));
 
// We also need to modify the home page so that it now points to the UserController login action.
//Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));  // default
Router::connect('/', array('controller' => 'users', 'action' => 'login'));  
Install Basic Components/Plugins

DebugKit

  • Download DebugKit from here: https://github.com/cakephp/debug_kit
  • Unpack to [cakephp]/app/Plugin directory.
  • Edit [cakephp]/app/Config/bootstrap.php and uncomment the following:
    CakePlugin::loadAll(); // Loads all plugins at once (optional)
    CakePlugin::load('DebugKit');
  • Edit [cakephp]/app/Config/core.php and uncomment one of the following:
    //Configure::write('debug', 0);    // for production mode
    Configure::write('debug', 1);    // for development mode 
    //Configure::write('debug', 2);  // for development mode (with sql dump)
  • Include the toolbar component in your [cakephp]/app/Controller/AppController.php:
    class AppController extends Controller 
    {
      public $components = array('DebugKit.Toolbar', ...);
      ...
    }

Articles

Authentication

AuthorizeNetComponent

  • Include the following file [cakephp/app/Controller/Component/AuthorizeNetComponent.php]:
    <?php  
    // Source: http://bakery.cakephp.org/articles/gstoner/2008/03/12/authorize-net-aim-integration-component
     
    //class AuthorizeNetComponent extends Object   // used in cakephp 1.x
    class AuthorizeNetComponent extends Component
    { 
        // Created by: Graydon Stoner - www.getstonered.com 
        // Upgraded to CakePHP 2.x by: Siegwart Mayr
        // Added functionality: Siegwart Mayr
     
        //////////// Controller Usage \\\\\\\\\\\\\ 
        /* 
        class MyController extends AppController
        {
          var $name = 'MyController';
          $components = array('AuthorizeNet', ...);
          ...
          function chargeCard()
          {
            // You would need to add in necessary information here from your data collector
            $billinginfo = array("fname"   => "First", 
                                 "lname"   => "Last", 
                                 "company" => "Acme Inc.", 
                                 "address" => "123 Fake St. Suite 0", 
                                 "city"    => "City", 
                                 "state"   => "ST", 
                                 "zip"     => "90210", 
                                 "country" => "USA"); 
     
            $shippinginfo = array("fname"   => "First", 
                                  "lname"   => "Last", 
                                  "company" => "Acme Inc.", 
                                  "address" => "123 Fake St. Suite 0", 
                                  "city"    => "City", 
                                  "state"   => "ST", 
                                  "zip"     => "90210", 
                                  "country" => "USA"); 
     
            $response = $this->AuthorizeNet->chargeCard('########', '##############', '4111111111111111', '01', '2010', '123', 
                true, 110, 5, 5, "Purchase of Goods", $billinginfo, "customeremail@example.com", "555-555-5555", $shippinginfo, 'INV123', false); 
     
            $response:Array = $this->AuthorizeNet->chargeCard($loginid:String, $trankey:String, $ccnum:String, $ccexpmonth:String, $ccexpyear:String, $ccver:String, 
                $live:Boolean, $amount:Number, $tax:Number, $shipping:Number, $desc:String, $billinginfo:Array, $email:String, $phone:String, $shippinginfo:Array, 
                $invoicenum:String, $testmode:Boolean);
          }
        } 
        ////////// USAGE NOTES \\\\\\\\\\\\ 
     
        PARAMETERS 
        $loginid         : Your Authorize.net Login ID 
        $trankey         : Your Authorize.net Transaction Key 
        $ccnum           : The system removes any spaces in the string to meet Authorize.net requirements 
        $ccexpmonth      : 2 digit month string 
        $ccexpyear       : 2 or 4 digit year string 
        $ccver           : The 3 or 4 digit card verificaton code found on the back of Visa/Mastercard and the front of AmEx
        $live            : Whether to process as a live or test transaction - true : Live Transcation - false : Test Transaction
        $amount          : Total amount of the transaction. This must include both tax and shipping if applicable. 
        $tax             : Tax amount charged (if any) 
        $shipping        : Shipping cost (if any) 
        $desc            : Description of the transaction to be logged into Authorize.net system 
        $billinginfo     : Associative Array containing values for customer billing details 
        $email           : Customer email 
        $phone           : Customer phone 
        $billinginfo     : Associative Array containing values for customer shipping details 
        $invoicenum      : The merchant-assigned invoice number for the transaction
        $testmode        : transaction is a test (true) or not (false). Use Visa test credit card number “4222222222222”, 
                           and to test the AVS response reason code (eg. number 27), submit the test transaction with 
                           the credit card number “4222222222222” and the amount matching the AVS code (eg “27.00.”)
     
        RESPONSE 
        $response : Array (1 based) containing the Payment Gateway Reasons fields  
     
        // Important Response Values 
        $response[1]  = Response Code (1 = Approved, 2 = Declined, 3 = Error, 4 = Held for Review) 
        $response[2]  = Response Subcode (Code used for Internal Transaction Details) 
        $response[3]  = Response Reason Code (Code detailing response code) 
        $response[4]  = Response Reason Text (Text detailing response code and response reason code) 
        $response[5]  = Authorization Code (Authorization or approval code - 6 characters) 
        $response[6]  = AVS Response (Address Verification Service response code - A, B, E, G, N, P, R, S, U, W, X, Y, Z)
                        (A, P, W, X, Y, Z are default AVS confirmation settings - Use your Authorize.net Merchant Interface to change these settings)
                        (B, E, G, N, R, S, U are default AVS rejection settings - Use your Authorize.net Merchant Interface to change these settings)
        $response[7]  = Transaction ID (Gateway assigned id number for the transaction) 
        $response[8]  = Transaction Invoice Number (Merchant assigned invoice number for the transaction) 
        $response[9]  = Transaction Description (Merchant assigned description for the transaction) 
        $response[10] = Transaction Amount (Merchant assigned amount for the transaction) 
        $response[11] = Payment method (CC, ECHECK)
        $response[12] = Transaction type (AUTH_CAPTURE, AUTH_ONLY, CAPTURE_ONLY, CREDIT, PRIOR_AUTH_CAPTUREVOID)
        $response[13] = Customer ID (Merchant-assigned)
        $response[14] = First name associated with the customer’s billing address
        $response[15] = Last name associated with the customer’s billing address
        $response[16] = Company associated with the customer’s billing address
        $response[17] = Street for customer’s billing address
        $response[18] = City for customer’s billing address
        $response[19] = State for customer’s billing address
        $response[20] = ZIP Code for customer’s billing address
        $response[21] = Country for customer’s billing address
        $response[22] = Phone for customer’s billing address
        $response[23] = Fax for customer’s billing address
        $response[24] = Email
        $response[25] = First name for shipping address
        $response[26] = Last name for shipping address
        $response[27] = Company name for shipping address
        $response[28] = Street for shipping address
        $response[29] = City for shipping address
        $response[30] = State for shipping address
        $response[31] = ZIP Code for shipping address
        $response[32] = Country for shipping address
        $response[33] = Tax
        $response[34] = Duty
        $response[35] = Freight
        $response[36] = Tax Exempt
        $response[37] = Purchase Order Number
        $response[38] = MD5 Hash (Gateway generated MD5 has used to authenticate transaction response) 
        $response[39] = Card Code Response (CCV Card Code Verification response code:
                        M = Match, N = No Match, P = No Processed, S = Should have been present, U = Issuer unable to process request)
        $response[40] = Cardholder Authentication Verification Response
        $response[51] = Account Number (Last 4-digits Cr Card Number with XXXX prefix)
        $response[52] = Card Type (Visa, MasterCard, American Express, Discover)
        $response[53] = Split Tender ID
        $response[54] = Requested Amount
        $response[55] = Balance on card
     
        For more information about the Authorize.net AIM response consult their 
        AIM Implementation Guide at http://developer.authorize.net/guides/AIM/ and 
        go to Section Four : Fields in the Payment Gateway Response for more details. 
     
        NOTES 
        This component is meant to abstract payment processing on a website.  
        As varying sites require different requirements for information, security, 
        or card processing (like changing Address Verification requirement) the 
        component does not try to provide any logic to determine if a transaction 
        was successful. It is up to the user implementing this code to process the 
        response array and provide response accordingly. 
     
        */ 
     
     
        // class variables go here 
        public $arrLastResponse = array();
     
        //---------------------------------------------------------------------------------------------
        // description:
        // parameters :
        // return     :
        //---------------------------------------------------------------------------------------------
        // function startup(&$controller)  // used in cakephp 1.x
        function startup(Controller $controller)
        { 
            parent::startup($controller);
     
            // This method takes a reference to the controller which is loading it. 
            // Perform controller initialization here. 
            $this->arrLastResponse = array();
        } 
     
        //---------------------------------------------------------------------------------------------
        // description: Charge credit card with the specified data.
        // parameters : $loginid, $trankey, $ccnum, $ccexpmonth, $ccexpyear, $ccver, $live, 
        //              $amount, $tax, $shipping, $desc, $billinginfo, $email, $phone, $shippinginfo, $invoicenum, $testmode
        // return     : $responsearray
        //---------------------------------------------------------------------------------------------
        function chargeCard($loginid, $trankey, $ccnum, $ccexpmonth, $ccexpyear, $ccver, $live, 
                $amount, $tax, $shipping, $desc, $billinginfo, $email, $phone, $shippinginfo, $invoicenum, $testmode) 
        {
            // setup variables 
            $ccexp = $ccexpmonth . '/' . $ccexpyear; 
     
            $DEBUGGING                    = 1;                # Display additional information to track down problems
            $TESTING                      = 1;                # Set the testing flag so that transactions are not live 
            $ERROR_RETRIES                = 2;                # Number of transactions to post if soft errors occur 
     
            $auth_net_login_id            = $loginid; 
            $auth_net_tran_key            = $trankey; 
            ###  Uncomment the appropriate line for test or live merchant accounts 
            //$auth_net_url               = "https://certification.authorize.net/gateway/transact.dll";   // test account
            $auth_net_url                 = "https://secure.authorize.net/gateway/transact.dll";          // live account
     
            $authnet_values               = array( 
                "x_login"                 => $auth_net_login_id, 
                "x_version"               => "3.1", 
                "x_delim_char"            => "|", 
                "x_delim_data"            => "TRUE", 
                "x_url"                   => "FALSE", 
                "x_type"                  => "AUTH_CAPTURE", 
                "x_method"                => "CC", 
                "x_tran_key"              => $auth_net_tran_key, 
                "x_relay_response"        => "FALSE", 
                "x_card_num"              => str_replace(" ", "", $ccnum), 
                "x_card_code"             => $ccver, 
                "x_exp_date"              => $ccexp, 
                "x_description"           => $desc, 
                "x_amount"                => $amount, 
                "x_tax"                   => $tax, 
                "x_freight"               => $shipping, 
                "x_first_name"            => $billinginfo["fname"], 
                "x_last_name"             => $billinginfo["lname"],
                "x_company"               => $billinginfo["company"],
                "x_address"               => $billinginfo["address"], 
                "x_city"                  => $billinginfo["city"], 
                "x_state"                 => $billinginfo["state"], 
                "x_zip"                   => $billinginfo["zip"], 
                "x_country"               => $billinginfo["country"], 
                "x_email"                 => $email, 
                "x_phone"                 => $phone, 
                "x_ship_to_first_name"    => $shippinginfo["fname"], 
                "x_ship_to_last_name"     => $shippinginfo["lname"], 
                "x_ship_to_company"       => $shippinginfo["company"],
                "x_ship_to_address"       => $shippinginfo["address"], 
                "x_ship_to_city"          => $shippinginfo["city"], 
                "x_ship_to_state"         => $shippinginfo["state"], 
                "x_ship_to_zip"           => $shippinginfo["zip"], 
                "x_ship_to_country"       => $shippinginfo["country"], 
                "x_invoice_num"           => $invoicenum,
                "x_test_request"          => ($ccnum == '4222222222222' ? true : $testmode),  // always set testmode on when using test cr card number
            );  
     
            $fields = ""; 
            foreach ( $authnet_values as $key => $value ) $fields .= "$key=" . urlencode( $value ) . "&"; 
     
            /////////////////////////////////////////////////////////// 
     
            // Post the transaction (see the code for specific information) 
     
     
            ###  Uncomment the appropriate line BELOW for test or live merchant accounts 
            //$ch = curl_init("https://certification.authorize.net/gateway/transact.dll");  // test account
            $ch = curl_init("https://secure.authorize.net/gateway/transact.dll");           // live account
            //curl_setopt($ch, CURLOPT_URL, "https://secure.authorize.net/gateway/transact.dll"); 
            curl_setopt($ch, CURLOPT_HEADER, 0);                          // set to 0 to eliminate header info from response 
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);                  // Returns response data instead of TRUE(1) 
            curl_setopt($ch, CURLOPT_POSTFIELDS, rtrim( $fields, "& " )); // use HTTP POST to send form data 
     
            ### Go Daddy Specific CURL Options 
            //curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, true);  
            //curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);  
            //curl_setopt($ch, CURLOPT_PROXY, 'http://proxy.shr.secureserver.net:3128');  
            //curl_setopt($ch, CURLOPT_TIMEOUT, 120); 
            ### End Go Daddy Specific CURL Options 
     
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // uncomment this line if you get no gateway response. ###
            $resp = curl_exec($ch); // execute post and get results 
            curl_close ($ch); 
     
            // Parse through response string 
     
            $text = $resp; 
            $h = substr_count($text, "|"); 
            $h++; 
            $responsearray = array(); 
     
            for($j=1; $j <= $h; $j++)
            { 
                $p = strpos($text, "|"); 
     
                if ($p === false)  // note: three equal signs 
                {
                    //  x_delim_char is obviously not found in the last go-around 
                    // This is final response string 
                    $responsearray[$j] = $text; 
                } 
                else 
                { 
                    $p++; 
                    //  get one portion of the response at a time 
                    $pstr = substr($text, 0, $p); 
     
                    //  This prepares the text and returns one value of the submitted 
                    //  and processed name/value pairs at a time.
                    //  For AIM-specific interpretations of the responses,
                    //  please consult the AuthorizeNet AIM Guide, and look up 
                    //  the section called Gateway Response API.
                    $pstr_trimmed = substr($pstr, 0, -1); // removes "|" at the end 
     
                    if($pstr_trimmed=="")
                    { 
                        $pstr_trimmed=""; 
                    } 
     
                    $responsearray[$j] = $pstr_trimmed; 
     
                    // remove the part that we identified and work with the rest of the string 
                    $text = substr($text, $p); 
                } // end if $p === false 
     
            } // end parsing for loop 
     
            $this->arrLastResponse = $responsearray;
            //print_r($responsearray);  // debug
            return $responsearray; 
     
        } // end chargeCard function 
     
        //---------------------------------------------------------------------------------------------
        // description:
        // parameters :
        // return     :
        //---------------------------------------------------------------------------------------------
        function testChargeCard() 
        {
            $billinginfo = array("fname"   => "John", 
                             "lname"   => "Doe", 
                             "company" => "Acme Inc.", 
                             "address" => "123 Fake St. Suite 0", 
                             "city"    => "Longwood", 
                             "state"   => "FL", 
                             "zip"     => "32750", 
                             "country" => "United States"); 
     
            $shippinginfo = array("fname"   => "John", 
                              "lname"   => "Doe", 
                              "company" => "Acme Inc.", 
                              "address" => "123 Fake St. Suite 0", 
                              "city"    => "Longwood", 
                              "state"   => "FL", 
                              "zip"     => "32750", 
                              "country" => "United States");
     
            //$loginid      = '92a6ZYS8Mhn';        // AuthorizeNet API login ID
            //$trankey      = '6CG8xU3ZB346WjhU';   // AuthorizeNet Transaction Key
            $loginid      = Configure::read('Company.AuthorizeNetLoginID');   // AuthorizeNet API login ID
            $trankey      = Configure::read('Company.AuthorizeNetTransKey');  // AuthorizeNet Transaction Key
            $ccnum        = '4222222222222';      // Visa test number
            $ccexpmonth   = '12';
            $ccexpyear    = '2014';
            $ccver        = '123';
            $live         = false;
            $amount       = '1.00';  // amount to charge.  NOTE: In testmode, the amount is the code to use for testing the response reason. 
                                     // For example, for response reason code number 27 (AVS address mismatch), submit the test transaction with 
                                     // the credit card number '4222222222222' and the amount '27.00.'
            $tax          = '0.00';  // tax charge
            $shipping     = '0.00';  // shipping charge
            $desc         = 'Workshop Registration: FL_2014';
            $email        = Configure::read('Workshop.Payment.NotificationEmailRecipientsForTest'); // Eg: 'smayr@acme.com';
            $phone        = '407-333-4444';
            $invoicenum   = 'INV123';
            $testmode     = true;
     
            // Method (x_method):			CC
            // Transaction Type (x_type):		auth_capture
            // Customer ID (x_cust_id):		FL0077
            // Company (x_company):			Acme
     
            $responsearray = $this->chargeCard($loginid, $trankey, $ccnum, $ccexpmonth, $ccexpyear, $ccver, $live, 
                $amount, $tax, $shipping, $desc, $billinginfo, $email, $phone, $shippinginfo, $invoicenum, $testmode);
            //print_r($responsearray);  // debug
            return $responsearray; 
        }
     
        //---------------------------------------------------------------------------------------------
        // description:
        // parameters :
        // return     :
        //---------------------------------------------------------------------------------------------
        function GetResponseStr($idx)
        {
            if ($this->arrLastResponse != null)
            {
                switch($idx)
                {
                    case 1: // Response Code
                        $msg = 'Credit Card Transaction Response: ';
                        switch($this->arrLastResponse[1])
                        {
                            case 1:  $msg .= 'Approved'; break;
                            case 2:  $msg .= 'Declined'; break;
                            case 3:  $msg .= 'Error';    break;
                            case 4:  $msg .= 'Held for Review'; break;
                            default: $msg .= 'Error';    break;
                        }
                        $msg .= ' (Reason Code ' . $this->arrLastResponse[3] . '). <br>' . $this->arrLastResponse[4]; // Response Reason Code (3) and Text (4)
                        break;
     
                    case 6:
                        // Address Verification Service (AVS) response:
                        // (A, P, W, X, Y, Z are default AVS confirmation settings)
                        // (B, E, G, N, R, S, U are default AVS rejection settings)
                        //  A = Address (Street) matches, ZIP does not
                        //  B = Address information not provided for AVS check
                        //  E = AVS error
                        //  G = Non-U.S. Card Issuing Bank
                        //  N = No Match on Address (Street) or ZIP
                        //  P = AVS not applicable for this transaction
                        //  R = Retry—System unavailable or timed out
                        //  S = Service not supported by issuer
                        //  U = Address information is unavailable
                        //  W = Nine digit ZIP matches, Address (Street) does not
                        //  X = Address (Street) and nine digit ZIP match
                        //  Y = Address (Street) and five digit ZIP match
                        //  Z = Five digit ZIP matches, Address (Street) does not
                        $msg = 'Address verification: ';
                        switch($this->arrLastResponse[6])
                        {
                            case 'A':  $msg .= 'Address (Street) matches, ZIP does not.'; break;
                            case 'B':  $msg .= 'Address information not provided for AVS check.'; break;
                            case 'E':  $msg .= 'AVS error.'; break;
                            case 'G':  $msg .= 'Non-U.S. Card Issuing Bank.'; break;
                            case 'N':  $msg .= 'No Match on Address (Street) or ZIP.'; break;
                            case 'P':  $msg = ''; break; // Clear message since AVS is not applicable here //$msg .= 'AVS not applicable for this transaction.'; break;
                            case 'R':  $msg .= 'Retry—System unavailable or timed out.'; break;
                            case 'S':  $msg .= 'Service not supported by issuer.'; break;
                            case 'U':  $msg .= 'Address information is unavailable.'; break;
                            case 'W':  $msg .= 'Nine digit ZIP matches, Address (Street) does not.'; break;
                            case 'X':  $msg .= 'Address (Street) and nine digit ZIP match.'; break;
                            case 'Y':  $msg .= 'Address (Street) and five digit ZIP match.'; break;
                            case 'Z':  $msg .= 'Five digit ZIP matches, Address (Street) does not.'; break;
                            default:   $msg  = ''; break;  // clear message
                        }
                        break;
     
                    case 39:
                        // Card Code Verification (CCV) response code:
                        //  M = Match, N = No Match, P = No Processed, S = Should have been present, U = Issuer unable to process request
                        $msg = 'Card Code Verification (CCV) Response: ';
                        switch($this->arrLastResponse[39])
                        {
                            case 'M':  $msg = ''; break; // clear message since it is a match //$msg .= 'Match.'; break;
                            case 'N':  $msg .= 'No Match.'; break;
                            case 'P':  $msg .= 'Not Processed.'; break;
                            case 'S':  $msg .= 'Should have been present.'; break;
                            case 'U':  $msg .= 'Issuer unable to process request.'; break;
                            default:   $msg = ''; break;  // clear message
                        }
                        break;
     
                    case 40:
                        // $response[40] = Cardholder Authentication Verification (CAVV) Response
                        // Value: The cardholder authentication verification response code
                        // Format: Blank or not present = CAVV not validated
                        // - 0 = CAVV not validated because erroneous data was submitted
                        // - 1 = CAVV failed validation
                        // - 2 = CAVV passed validation
                        // - 3 = CAVV validation could not be performed; issuer attempt incomplete
                        // - 4 = CAVV validation could not be performed; issuer system error
                        // - 5 = Reserved for future use
                        // - 6 = Reserved for future use
                        // - 7 = CAVV attempt – failed validation – issuer available (U.S.-issued card/non-U.S acquirer)
                        // - 8 = CAVV attempt – passed validation – issuer available (U.S.-issued card/non-U.S. acquirer)
                        // - 9 = CAVV attempt – failed validation – issuer unavailable (U.S.-issued card/non-U.S. acquirer)
                        // - A = CAVV attempt – passed validation – issuer unavailable (U.S.-issued card/non-U.S. acquirer)
                        // - B = CAVV passed validation, information only, no liability shift
                        $msg = 'Cardholder Authentication Verification (CAVV) Response: ';
                        switch($this->arrLastResponse[40])
                        {
                            case '0':  $msg .= 'CAVV not validated because erroneous data was submitted.'; break; 
                            case '1':  $msg .= 'CAVV failed validation.'; break;
                            case '2':  $msg .= 'CAVV passed validation'; break;
                            case '3':  $msg .= 'CAVV validation could not be performed; issuer attempt incomplete'; break;
                            case '4':  $msg .= 'CAVV validation could not be performed; issuer system error'; break;
                            case '5':  $msg .= 'Reserved for future use'; break;
                            case '6':  $msg .= 'Reserved for future use'; break;
                            case '7':  $msg .= 'CAVV attempt – failed validation – issuer available (U.S.-issued card/non-U.S acquirer)'; break;
                            case '8':  $msg .= 'CAVV attempt – passed validation – issuer available (U.S.-issued card/non-U.S. acquirer)'; break;
                            case '9':  $msg .= 'CAVV attempt – failed validation – issuer unavailable (U.S.-issued card/non-U.S. acquirer)'; break;
                            case 'A':  $msg .= 'CAVV attempt – passed validation – issuer unavailable (U.S.-issued card/non-U.S. acquirer)'; break;
                            case 'B':  $msg .= 'CAVV passed validation, information only, no liability shift'; break;
                            default:   $msg  = ''; break;  // clear message
                        }
                        break;
     
                    case 51:
                        $msg = 'Credit Card Number: ' . $this->arrLastResponse[51] . '. ';
                        break;
     
                    default:
                        $msg = '';
                }
            }
            return $msg;
        }
    }    
    ?>

Add component references to the controller using it:

<?php
  class MyController extends AppController
  {
    var $name = 'MyController';
    $components = array('AuthorizeNet', ...);
    ...
  }
?>

Use it. Call the component from the controller needing it:

<?php
  class MyController extends AppController
  {
    ...
    function chargeCard()
    {
      // You would need to add in necessary information here from your data collector
      $billinginfo = array("fname"   => "First", 
                             "lname"   => "Last", 
                             "company" => "Acme Inc.", 
                             "address" => "123 Fake St. Suite 0", 
                             "city"    => "City", 
                             "state"   => "ST", 
                             "zip"     => "90210", 
                             "country" => "USA"); 
 
        $shippinginfo = array("fname"   => "First", 
                              "lname"   => "Last", 
                              "company" => "Acme Inc.", 
                              "address" => "123 Fake St. Suite 0", 
                              "city"    => "City", 
                              "state"   => "ST", 
                              "zip"     => "90210", 
                              "country" => "USA");
      $response = $this->AuthorizeNet->chargeCard('########', '##############', '4111111111111111', '01', '2010', '123', true, 110, 5, 5, "PurchaseofGoods", $billinginfo, "customeremail@example.com", 555-5555", $shippinginfo);
    }
  }
?>

The call to the component function chargeCard uses the following format:

$response:Array = $this->AuthorizeNet->chargeCard($loginid:String, $trankey:String, $ccnum:String, $ccexpmonth:String, $ccexpyear:String, $ccver:String, $live:Boolean, $amount:Number, $tax:Number, $shipping:Number, $desc:String, $billinginfo:Array, $email:String, $phone:String, $shippinginfo:Array);

PARAMETERS

  • $loginid : Your Authorize.net Login ID
  • $trankey : Your Authorize.net Transaction Key
  • $ccnum : The system removes any spaces in the string to meet Authorize.net requirements
  • $ccexpmonth : 2 digit month string
  • $ccexpyear : 2 or 4 digit year string
  • $ccver : The 3 or 4 digit card verificaton code found on the back of Visa/Mastercard and the front of AmEx
  • $live : Whether to process as a live or test transaction - true : Live Transcation - false : Test Transaction
  • $amount : Total amount of the transaction. This must include both tax and shipping if applicable.
  • $tax : Tax amount charged (if any)
  • $shipping : Shipping cost (if any)
  • $desc : Description of the transaction to be logged into Authorize.net system
  • $billinginfo : Associative Array containing values for customer billing details
  • $email : Customer email
  • $phone : Customer phone
  • $billinginfo : Associative Array containing values for customer shipping details

RESPONSE

  • $response : Array (1 based) containing the Payment Gateway Resonse fields

The response is an array of all the response codes from Authorize.net's system. Details on all these responses is available at http://developer.authorize.net/guides/AIM/. Here are some of the most important fields:

    $response[1] = Response Code (1 = Approved, 2 = Declined, 3 = Error, 4 = Held for Review) 
    $response[2] = Response Subcode (Code used for Internal Transaction Details) 
    $response[3] = Response Reason Code (Code detailing response code) 
    $response[4] = Response Reason Text (Text detailing response code and response reason code) 
    $response[5] = Authorization Code (Authorization or approval code - 6 characters) 
    $response[6] = AVS Response (Address Verification Service response code - A, B, E, G, N, P, R, S, U, W, X, Y, Z)
                    (A, P, W, X, Y, Z are default AVS confirmation settings - Use your Authorize.net Merchant Interface to change these settings)
                    (B, E, G, N, R, S, U are default AVS rejection settings - Use your Authorize.net Merchant Interface to change these settings)
    $response[7] = Transaction ID (Gateway assigned id number for the transaction) 
    $response[38] = MD5 Hash (Gateway generated MD5 has used to authenticate transaction response) 
    $response[39] = Card Code Response (CCV Card Code Verification response code - M = Match, N = No Match, P = No Processed, S = Should have been present, U = Issuer unable to process request)

TCPDF

  • Create [cakephp]app/View/Layouts/pdf/default.ctp:
    <?php
      header("Content-type: application/pdf");
      echo $content_for_layout;
    ?>
  • In your Controller, for example in [cakephp]/app/Controller/ArticlesController.php, create a new action:
    public function create_pdf()
    {
        $users = $this->User->find('all');
        $this->set(compact('users'));
        $this->layout = '/pdf/default';
        $this->render('/Pdf/my_pdf_view');
    }
  • Create a new view file [cakephp]/app/View/Pdf/my_pdf_view.ctp:
    <?php
    App::import('Vendor','xtcpdf');
     
    $pdf = new XTCPDF('L', PDF_UNIT, 'A4', true, 'UTF-8', false);
    $pdf--->AddPage();
     
    $html = '</pre>
    <h1>hello world</h1>
    <pre>';
     
    foreach ( $posts as $post ){
        $html .= "\n<br/>" . $post['Post']['title'];
    }
    $pdf->writeHTML($html, true, false, true, false, '');
    $pdf->lastPage();
    
    echo $pdf->Output(APP . 'files/pdf' . DS . 'test.pdf', 'I' /* Dest: F = File to disk, I = Inline to browser */); 
    ?>

For example:

  • In controller, generate the data and call PDF generator:
        //---------------------------------------------------------------------------------------------
        // description: Generate packet labels form.
        // parameters :
        // return     :
        //---------------------------------------------------------------------------------------------
        public function GenFormPacketLabels($aWorkshopCode,  $aContentType="attendees", $id=0)
        {
            $this->GenFormData($aWorkshopCode, $aContentType, $id);
     
            $this->SetFormDimensions("PacketLabels");
        }
     
        //---------------------------------------------------------------------------------------------
        // description: Generate course evaluation form.
        // parameters :
        // return     :
        //---------------------------------------------------------------------------------------------
        private function GenFormData($aWorkshopCode, $aContentType="attendees", $id=0)
        {
            $attendees = array();
            $this->set('attendees', $attendees); 
     
            // Get workshop data
            if (!empty($aWorkshopCode)) 
            { 
                $workshop = ClassRegistry::init('Workshop')->find('first', array(
                    'conditions' => array('Workshop.Code' => $aWorkshopCode),
                    'recursive' => 0,
                )); 
                if (!$workshop) 
                {
                    throw new NotFoundException(__('Invalid workshop'));
                }
            }
            $this->set('workshop', $workshop);
     
            // Generate PDF report with custom data
            if ($this->request->is('post')) 
            {
                if ($this->request->data) 
                {
                    // Get custom name tag data
                    $attendees = $this->GenAttendeeRec($aWorkshopCode, $this->request->data);
                    $this->set('attendees', $attendees); 
     
                    // Set Header Response to PDF content type
                    $this->layout = '/pdf/default';
                    $this->response->type('application/pdf'); 
                    $this->render('/MyEntity/genlabels');   
                }
            }
        }
     
        //---------------------------------------------------------------------------------------------
        // description: Set form dimensions.
        // parameters : $aTemplateType - Template type (string) to use: PacketLabels, MailingLabels, NameTags.
        // return     : void
        //---------------------------------------------------------------------------------------------
        private function SetFormDimensions($aTemplateType)
        {
            $this->set('topmargin',      $this->GetAppSetting($aTemplateType.'TopMargin'));        // mm
            $this->set('leftmargin',     $this->GetAppSetting($aTemplateType.'LeftMargin'));       // mm
            $this->set('rightmargin',    $this->GetAppSetting($aTemplateType.'RightMargin'));      // mm
            $this->set('bottommargin',   $this->GetAppSetting($aTemplateType.'BottomMargin'));     // mm
            $this->set('intercolmargin', $this->GetAppSetting($aTemplateType.'InterColMargin'));   // mm
            $this->set('interrowmargin', $this->GetAppSetting($aTemplateType.'InterRowMargin'));   // mm
            $this->set('colsperpage',    $this->GetAppSetting($aTemplateType.'ColsPerPage'));      // label cols
            $this->set('rowsperpage',    $this->GetAppSetting($aTemplateType.'RowsPerPage'));      // label rows
            $this->set('cellborder',     $this->GetAppSetting($aTemplateType.'CellBorder'));       // 0: no border
                                         //0: no border (default), 1: frame, L: left, T: top, R: right, B: bottom
        }
  • Create view /app/View/MyEntity/genlabels.ctp:
    <!-- File: /app/View/MyEntity/genlabels.ctp -->
    <?php
    $headertitle = 'Annual Continuing Education Workshop';
    $headersubtitle = 'Packet Labels';
    
    require_once(APP . 'Lib' . DS . 'StringUtils.php');
    
    // Write() defaults
    $defaultfont  = 'helvetica';
    $height       = 0;
    $isbgfilled   = false;
    $isnewline    = true;
    $stretch      = 0;
    $isfirstline  = false;
    $isfirstblock = false;
    $heightmax    = 0;
    
    // Label defaults
    $unitsperpagewidth  = 216;  // mm for US Letter size (8.5 x 11 inches (216 mm x 279 mm)), Portrait orient.
    $unitsperpageheight = 279;  // mm for US Letter size (8.5 x 11 inches (216 mm x 279 mm)), Portrait orient.
    
    // Avery 88395/5395 (8 per page)
    // $leftmargin     = 18;  // mm
    // $topmargin      = 18;  // mm
    // $rightmargin    = 18;  // mm
    // $bottommargin   = 15;  // mm
    // $intercolmargin = 12;  // mm
    // $interrowmargin = 10;  // mm
    // $colsperpage    = 2;   // label columns
    // $rowsperpage    = 4;   // label rows
    
    // Avery 5264 (6 per page)
    // $leftmargin     = 5;   // mm
    // $topmargin      = 15;  // mm
    // $rightmargin    = 5;   // mm
    // $bottommargin   = 15;  // mm
    // $intercolmargin = 5;   // mm
    // $interrowmargin = 5;   // mm
    // $colsperpage    = 2;   // label columns
    // $rowsperpage    = 3;   // label rows
    
    //###---- User Modifiable Variables ----###
    //#
    //$topmargin      = 5;  // mm
    //$leftmargin     = 5;  // mm
    //$rightmargin    = 5;  // mm
    //$bottommargin   = 5;  // mm
    //$intercolmargin = 0;  // mm
    //$interrowmargin = 0;  // mm
    //$colsperpage    = 2;  // label columns
    //$rowsperpage    = 4;  // label rows
    //$cellborder     = 1;  // 0: no border (default), 1: frame, L: left, T: top, R: right, B: bottom
    $cellfill       = false;  // true: painted, false: transparent
    //#
    //################################
    
    $labelsperpage  = ($colsperpage * $rowsperpage);
    $cellwidth      = ($unitsperpagewidth - $leftmargin - ($intercolmargin * ($colsperpage-1)) - 
                         $rightmargin) / $colsperpage; 
    $cellheight     = ($unitsperpageheight - $topmargin - ($interrowmargin * ($rowsperpage-1)) - 
                         $bottommargin) / $rowsperpage;
    
    // define barcode style
    $barcodestyle = array(
        'position' => '',
        'align'    => 'C',
        'stretch'  => false,
        'fitwidth' => true,
        'cellfitalign' => '',
        'border'   => false,
        'hpadding' => 'auto',
        'vpadding' => 'auto',
        'fgcolor'  => array(0,0,0),
        'bgcolor'  => false, //array(255,255,255),
        'text'     => true,
        'font'     => 'helvetica',
        'fontsize' => 8,
        'stretchtext' => 4
    );
    
    //$aWorkshopName      = $workshop['Workshop']['Code'] . ' - ' . $workshop['Workshop']['Name'];
    $aWorkshopName = $this->Text->truncate(
        $workshop['Workshop']['Code'] . ' - ' . $workshop['Workshop']['Name'], 
        120 /* max chars per line */ / $colsperpage /* max chars */,
        array('ellipsis' => '...', 'exact' => false )
    );
    $aWorkshopLocation  = $workshop['Workshop']['Address'];
    ?>
               
    <?php
    // Include the main TCPDF library
    App::import('Vendor','xtcpdf');  
    
    // create new PDF document
    $pdf = new XTCPDF('P' /* Page orientation (P=portrait, L=landscape) */, 
                 PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
    
    // set document information
    $pdf->SetCreator(PDF_CREATOR);
    $pdf->SetAuthor(Configure::read('Company.Name'));
    $pdf->SetTitle($headertitle);
    $pdf->SetSubject($headersubtitle);
    $pdf->SetKeywords('');
    
    // set default header data
    $pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, $headertitle, $headersubtitle);
    
    // set header and footer fonts
    $pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
    $pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
    $pdf->setPrintHeader(false);  // do not print footer
    $pdf->setPrintFooter(false);  // do not print footer
    
    // set default monospaced font
    $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
    
    // set margins
    //$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
    $pdf->SetMargins($leftmargin, $topmargin, $rightmargin);
    $pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
    $pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
    
    // set auto page breaks
    //$pdf->SetAutoPageBreak(FALSE, PDF_MARGIN_BOTTOM);
    $pdf->SetAutoPageBreak(FALSE, $bottommargin);
    
    // set image scale factor
    $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
    
    // set some language-dependent strings (optional)
    if (@file_exists(dirname(__FILE__).'/lang/eng.php')) {
        require_once(dirname(__FILE__).'/lang/eng.php');
        $pdf->setLanguageArray($l);
    }
    
    // ---------------------------------------------------------
    // Add Page
    // ---------------------------------------------------------
    set_time_limit(0);  // set execution time limit to None
    
    // ---------------------------------------------------------
    // Doc Content
    $pdf->SetFont($defaultfont, 'B', 18);
    
    $labelcount  = 0;
    $isLineBreak = 0;
    $rowcount    = 0;
    foreach($attendees as $row) 
    { 
        if (($labelcount % $labelsperpage) == 0) { $pdf->AddPage(); $rowcount = 0; }
        
        $colcount = ($labelcount % $colsperpage);
        if ($colcount == 0) 
        { 
            // First cell in row
            $Xoffset = $leftmargin; 
            $Yoffset = $topmargin + (($cellheight + $interrowmargin) * $rowcount); 
            $isLineBreak = 0; 
        } 
        else 
        { 
            // Any cell (except First cell) in row
            $Xoffset = $leftmargin + (($cellwidth  + $intercolmargin) * $colcount); 
            $Yoffset = $topmargin  + (($cellheight + $interrowmargin) * $rowcount); 
            $isLineBreak = 0; 
            
            // Last cell in row
            if ($colcount == ($colsperpage-1))
            {
                $isLineBreak = 1; 
                $rowcount++;
            } 
        }
        
        if (!empty($row['Registration']['LastName']) && !empty($row['Registration']['FirstName']))
        {
            $aFullName = StringUtils::nameize($row['Registration']['LastName'] . ', ' . 
                    $row['Registration']['FirstName']);  //require_once(APP . 'Lib' . DS . 'StringUtils.php');
        } else {
            $aFullName = "";
        }    
        $aPacketID = $row['Registration']['PacketID'];
        $aPacketID = ( ($aPacketID > 0) ? (substr($aPacketID, 0, 4) . '-' . substr($aPacketID, 4, 4)) : 0);
        $pdf->SetFont($defaultfont, 'B', 18);
        //$aPacketLabel = "\n" . $aFullName . "\n" . $aPacketID . "\n" . $labelcount; // with counter (debug)
        $aPacketLabel = "\n" . $aFullName . "\n" . $aPacketID;
    
        // Barcode (print in X,Y coordinates of next cell)
        $x = $pdf->GetX();  // save X pos
        $y = $pdf->GetY();  // save Y pos
        $Xoffsetbarcode = $Xoffset + (($cellwidth - 50 /* barcode width */) / 2);
        $Yoffsetbarcode = $Yoffset + (($cellheight - 15 /* barcode height */) / 2) + 18 /* offset from ctr */;
        $pdf->write1DBarcode($aPacketID, 'C128', $Xoffsetbarcode, $Yoffsetbarcode, 
               50 /* width */, 15 /* height */, 0.4 /* bar resolution */, $barcodestyle, 'N');
        
        // Workshop name
        $pdf->SetXY($Xoffset, $Yoffset); 
        $pdf->SetFont($defaultfont, '', 8);
        $pdf->Write($height, $aWorkshopName,  '', 0, 'L', 0 /*$isnewline*/, $stretch, 
                $isfirstline, $isfirstblock, $heightmax);
    
        // Cell
        $pdf->SetXY($x, $y); // Reset X,Y so wrapping cell wraps around the barcode's cell.
        $pdf->SetFont($defaultfont, 'B', 22);
        $pdf->MultiCell($cellwidth, $cellheight, $aPacketLabel, $cellborder, 'C' /* align */, 
                $cellfill, $isLineBreak, $Xoffset, $Yoffset, true /* reset height */, 'M');
        if ($isLineBreak) { $pdf->Ln(1); }
        
        $labelcount++;
    }
    
    //$pdf->SetFont($defaultfont, '', 8);
    //date_default_timezone_set('America/New_York'); 
    //$pdf->Write($height, 'Generated: ' . date("Y-m-d H:i:s"), '', $isbgfilled, 'L', 
               true /* newline */, $stretch, $isfirstline, $isfirstblock, $heightmax);
    
        
    // Close and output PDF document
    ob_end_clean();    // Clean (erase) the output buffer and turn off output buffering
    ob_start();      // Turn on output buffering, to avoid errors
    $pdf->Output($workshop['Workshop']['Code'] . '-' . 'PacketLabels.pdf', 'I' /* Inline file dest */);
    //ob_end_flush();  // Turn off output buffering
    
    // ---------------------
    // End
    // ---------------------
    ?>

StringUtils

  • Include this file in [cakephp]/app/Lib/StringUtils.php:
    <?php
    /**
     * String handling methods.
     *
     * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
     * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
     *
     * Licensed under The MIT License
     * For full copyright and license information, please see the LICENSE.txt
     * Redistributions of files must retain the above copyright notice.
     *
     * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
     * @link          http://cakephp.org CakePHP(tm) Project
     * @package       Cake.Utility
     * @since         CakePHP(tm) v 1.2.0.5551
     * @license       http://www.opensource.org/licenses/mit-license.php MIT License
     */
     
    /**
     * String handling methods.
     *
     *
     * @package       Cake.Utility
     */
    class StringUtils
    {
        //---------------------------------------------------------------------------------------------
        // description: Generate correct first letter uppercase names.
        //              Usage: StringUtils::nameize($aName);  //require_once(APP . 'Lib' . DS . 'StringUtils.php');
        // parameters : $str, $delimiters
        // return     : $str (formatted string)
        //---------------------------------------------------------------------------------------------
        public static function nameize($str, $delimiters = array("'", "-", " ", "Mc"))
        {   
            // Check if string is all lowercase/uppercase, which would then need processing.
            $requiresprocessing = false;
            $testdata = split(" ", $str);
            foreach($testdata as $s)
            {
                if (ctype_lower($s) || ctype_upper($s))
                {
                    $requiresprocessing = true;
                    break;
                }
            }
     
            // Remove double spaces
            $str = trim(str_replace("  ", " ", $str));
     
            // Change to uppercase first letter of each name, including special cases.
            // Eg: O'connell to O'Connell, Perez-morales to Perez-Morales, and Mcdonald to McDonald
            // Params:
            //  $str          Contains the complete raw name string.
            //  $delimiters   An array containing the characters used as separators for capitalization. 
            //                If you don't pass anything, there are four in there as default.
            if ($requiresprocessing)
            {
                $str = strtolower($str);
                foreach ($delimiters as $delimiter)
                {
                    $pos = strpos($str, $delimiter);
                    if ($pos)
                    {
                        // Found one of the special characters in the array, 
                        // so lets split it up into chunks and capitalize each one.
                        $mend = '';
                        $a_split = explode($delimiter, $str);
                        foreach ($a_split as $chunk)
                        {
                            // Capitalize each portion of the string which was separated at a delimiter
                            $mend .= ucfirst($chunk) . $delimiter;
                        }
                        $str = substr($mend, 0, -strlen($delimiter));  // strip end delimiter
                    }    
                }
                return ucfirst($str);
            }
            else
            {
                return $str;
            }
        }
    }
    ?>

SVGGraph

  • Unpack files to [cakephp]/app/Vendor/svggraph.
  • Create file [cakephp]/app/Vendor/xsvggraph.php:
    <?php
    App::import('Vendor','svggraph/SVGGraph');
     
    class XSVGGraph extends SVGGraph
    {
    }
    ?>
  • Create a View to include graph (Eg: [cakephp]/app/View/MyEntity/graphview.ctp):
    <?php
    //require_once 'SVGGraph.php';
    App::import('Vendor', 'xsvggraph');
    $graph = new SVGGraph(500, 400);
    $graph->Values(1, 4, 8, 9, 16, 25, 27);
    $graph->Render('LineGraph');
    ?>
  • To include graph in a PDF, edit a View (using TCPDF) to include graph (Eg: [cakephp]/app/View/MyEntity/pdfgraphview.ctp):
    App::import('Vendor','xtcpdf');
    $pdf = new XTCPDF('L' /* L=Letter, P=Portrait */, PDF_UNIT, 'Letter' /* Page Size */, true, 'UTF-8', false);
    $pdf->AddPage();
    //------------------------------
    // Graph (using SVGGraph)
    //------------------------------
    //require_once 'svggraph/SVGGraph.php';
    App::import('Vendor', 'xsvggraph');
    $graph = new XSVGGraph(500, 400);
    $graph->Values(1, 4, 8, 9, 16, 25, 27); 
    $output = $graph->fetch('LineGraph');
     
    // Feed it to TCPDF (Since fetch without options generates the XML declaration and doctype).
    // This should generate $output of the format:
    // <svg style="overflow: hidden; position: relative;" 
    //   xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
    //   width="1226" version="1.1" height="826">
    //   <image transform="matrix(1.0364,-0.3305,0.3305,1.0364,-41.846,108.0143)" 
    //     preserveAspectRatio="none" x="10" y="10" width="205" height="154" 
    //     xlink:href="wallpaper.jpg" opacity="1" stroke-width="1"></image>
    //   <rect transform="matrix(1.0364,-0.3305,0.3305,1.0364,-41.846,108.0143)" 
    //      x="165" y="114" width="50" height="50" r="0" rx="0" ry="0" 
    //      fill="#C0C0C0" stroke="#000" opacity="0" stroke-width="1"></rect>
    //   <image transform="matrix(1.1575,0.2385,-0.2385,1.1575,-442.1395,-145.4163)" 
    //      preserveAspectRatio="none" x="500" y="10" width="205" height="154" 
    //      xlink:href="wallpaper.jpg" opacity="1" stroke-width="1"></image>
    //   <rect transform="matrix(1.1575,0.2385,-0.2385,1.1575,-442.1395,-145.4163)" 
    //      x="655" y="114" width="50" height="50" r="0" rx="0" ry="0" fill="#C0C0C0" stroke="#000" 
    //      opacity="0" stroke-width="1"></rect>
    // </svg>
    // Feed it like this:
    $pdf->ImageSVG('@' . $output, $x=15, $y=30, $w='', $h='', 
              $link='http://www.tcpdf.org', $align='', $palign='', $border=1, $fitonpage=false);
     
    // Of course you can also save the output in a file, and then provide the path to the file:
    //$pdf->ImageSVG($file='images/file.svg', $x=15, $y=30, $w='', $h='', 
    //         $link='', $align='', $palign='', $border=0, $fitonpage=false); 
     
    $pdf->lastPage();
     
    echo $pdf->Output(APP . 'files/pdf' . DS . 'articles.pdf', 'I' /* Dest: F = File saved to disk, I = Inline to browser */); 

PHPExcel

In PhpExcel helper, edit function createdWorksheet() to look like this:

public function createWorksheet() {
    // load vendor classes
    App::import('Vendor', 'PHPExcel');  // <-- Check class name
 
    $this->_xls = new PHPExcel();
    $this->_row = 1;
 
    return $this;
}

In controller, add references to helper:

class MyController extends AppController 
{
   ...
   public $helpers = array('Html', 'Form', 'Session', ..., 'PhpExcel');  
   ...
}   

In controller, add action to generate data:

...
function actionGetData($id)
{
    $data = ClassRegistry::init('Customer')->find('all', array(
                'conditions' => array('Customer.id' => $id),
            )); 
 
    $this->set('data', $data); 
 
    // Create a view that does not display any html header code except for the Excel data.
    // To do this, set the layout to be 'ajax', which just happens to contain no html outside the main content.
    $this->layout = 'ajax';
}    

Create view. Eg: actiongetdata

// create new empty worksheet and set default font
$this->PhpExcel->createWorksheet()->setDefaultFont('Calibri', 12);
 
// define table cells
$table = array(
    array('label' => __('User'), 'filter' => true),
    array('label' => __('Type'), 'filter' => true),
    array('label' => __('Date')),
    array('label' => __('Description'), 'width' => 50, 'wrap' => true),
    array('label' => __('Modified'))
);
 
// add heading with different font and bold text
$this->PhpExcel->addTableHeader($table, array('name' => 'Cambria', 'bold' => true));
 
// add data
foreach ($data as $d) {
    $this->PhpExcel->addTableRow(array(
        $d['User']['name'],
        $d['Type']['name'],
        $d['User']['date'],
        $d['User']['description'],
        $d['User']['modified']
    ));
}
 
// close table 
$this->PhpExcel->addTableFooter();
 
// Save to Excel file
ob_end_clean();  // remove all output (very important, otherwise data is garbage)
this->PhpExcel->output('MyExcelFile.xlsx');
Delete Cached Models

After updating a model, clear the cache to see the changes on the site.

$ rm -f /app/tmp/cache/models/cake_model_*
$ rm -f /app/tmp/cache/persistent/cake_core_*