phpseclib is awesome

While looking for something to help php connect to a sftp server I stumbled across libphpsec which is a fantastic library that has no dependencies and works in all versions of php. The documentation takes a "cookbook" approch which works really well for me.

The real genius to this library is it makes no assumptions about your environment.
If a suitable native function doesn't exist, there is a pure php one to pick up the slack.
The following are implemented in pure php:

  • BigIntegers
  • RSA
  • SSH2
  • SFTP
  • X.509
  • Symmetric key encryption

    • AES
    • Rijndael
    • Twofish
    • Blowfish
    • DES
    • 3DES
    • RC4
    • RC2

    I'm amazed that someone loved this problem enough to do this much work on it and thankful he chose to open-source it.
    Terrafrost, if your ever able to make it to the Austin PHP Beverage Subgroup; (4th Wednesday) the drinks are on me guy.

     

Do something like “svn export” with git

Zend framework recently moved to git and I'm starting to integrate it into our release scripts.
The previous command used svn export and the tag for the release I wanted.
It took a little while to figure out how to do this with git:

git clone --depth 1 --branch release-1.12.3 https://github.com/zendframework/zf1.git /where/do/you/want/it/zf1/1.12.3/
rm -f -r /var/www/vhosts/ZendFramework/1.12.3/.git

A few differences from svn:

  • git has the complete revision history in every checkout. By adding the –depth 1, we're only getting the history relevant to our selected 'branch' and greatly speeding up the checkout of this giant project.
  • git doesn't do tags like svn/cvs. A tag isn't a branch, its a human friendly name for a revision hash. The command is –branch but it doesn't have to be a branch. It can also be a tag or commit hash. You'll get a warning about head being disconnected, its not relevant in my case because I'm not making change to or managing this folder with .git after I get it checked out.
  • git doesn't have an 'export' method because it doesn't need it. All the git revisions are in the .git folder in the root of the project instead of spread all over kingdom come like cvs and svn. Just delete the .git folder and now the project is no longer under git revision control. ( Modern versions of svn have a single folder, just like git. Thanks Alan. )

This helped a lot and has other possible solutions.
http://stackoverflow.com/questions/160608/how-to-do-a-git-export-like-svn-export

Use PHP-CLI to publish server stats via json

If you need great server monitoring, use copper egg. It inexpensive, easy to install and very very good.

If you happen to use PHP with Linux, a lot of usesful information can be extracted from the /proc filesystem. Enough to provide basic monitoring. The attached script dumps and processes the output from proc every minute as json.

Make sure to protect the directory you're outputing this into to.

Download livestats.php code

Is this a private IP address?

I need to show different content to folks who are outside our network.
This snippet will detect a private ip address using php's built in filter class.

function is_private_ip($ip) {
return !filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);
}

FILTER_FLAG_NO_PRIV_RANGE gets you:

"Fails validation for the following private IPv4 ranges:10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16.

Fails validation for the IPv6 addresses starting with FDor FC."

and FILTER_FLAG_NO_RES_RANGE gets you:

"Fails validation for the following reserved IPv4 ranges:0.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24 and224.0.0.0/4. This flag does not apply to IPv6 addresses."

Source: PHP Docs

Creating a Magento Payment Module – Part 3 – Model, Controllers and Events

There are many tutorials out there which show parts of implementing a payment module. None completely build the module. They all stop short of showing how they implemented their nameless payment method.

This is part 3 of the tutorial. Here's part 1 and part 2 in case you missed them.

This post will walk through the model, action controllers and how they interact with the mockpay api.

My/Mockpay/Model/Standard.php

This model extends Mage_Payment_Model_Method_Abstract and if you look at the code of the base model, you'll see it has a lot of protected boolean attributes. These attributes are probed by the various consumers of these payment methods to figure out which features of the payment API our module supports.

Most of the modules I looked at for examples do this by overriding the properties instead of just setting them in the constructor. Our model defines four properties:

  • $_canUseForMultiShipping which enables/disables this method to be used for orders split up and shipped to many addresses,
  • $_canUseInternal which enables/disables using this method from the admin order screen,
  • $_code which is the unique payment method code for this module. It should match the code defined in the config.xml file. Its just text.
  • $_isInitializeNeeded, which enables a call to the initialize method when payment is captured.

The model::initialize() method is called when the order is placed. (Last step of the checkout process when the "place order" button is clicked.)
Looking at other modules is a great way to figure out how this code should work and if you look at the paypal or authorize.net modules you'll find a bunch more options are configured. These modules do the full authorize/capture process. Authorize occurs when the payment method is selected and the capture method is called when you click the "place order" button is clicked.

My module is very simple, needed only one method to be called at the very end of the payment process.
I opted to use initialize() instead of capture/authorizenbsp;because it always occurs at the same point in the process and I observed that initialize is only called in one place. I didn't find that to be true of the other methods.

In my initialize method, I'm setting the order state to "pending payment". This provides a clue to the folks working with the order in the backend that no payment has been collected for this order yet. I'm also connecting to the mockpay api and sending the order details. Mockpay will respond by providing a session token which will be unique to this order. The token is used to associate the customer on our site to the order details on the mockpay site with the order info and amount we're requesting. This is also where we'll inform mockpay about the cancel, error and success urls for this order.

Once payment is completed or canceled. The customer will be redirected back to our site. At that point we have a little more work to do with the order to either make an invoice and change the order state if successful or cancel it if the order fails or is canceled.

We'll use action controllers to handle these requests.

These are in the controllers/StandardController.php file. This is also extending an existing magento resource called "Mage_Core_Controller_Front_Action".

The successAction() will handle the success condition of the api where payment was completed successfully.
We'll get a token back from the mockpay api and we'll be able to use the token to query the api to get more details about the payment.

If everything checks out, we can change the state of the order from STATE_PENDING_PAYMENT to STATE_NEW, so its ready for someone on the store to ship and complete. This is also where we'll convert the quote into an invoice and mark it as paid. I skipped this step in the first version and it means someone on the backend has to do the extra step of creating an invoice and marking it as paid in magento.

Once all these steps are completed, I can then redirect the customer to the order complete page.

The other possible conditions are cancel, the person doesn't want to pay or failure where payment can't be completed because of lack of funds. I have these two conditions routed to the same action, the cancelAction().

Cancel will make the quote inactive and call the order objects cancel method.

With these actions in place, we have a functional payment module integrated with the mock pay api.

I've tried to comment as much as possible in the code so hopefully it will be instructive as you attempt to create your own payment method.

The full code for this payment module can be found on github.