Archive for December, 2011

We are currently working on an OpenID consumer implementation. We looked into the Zend_OpenID - unfortunately it did not work. We are unable to get it work with Google. The remaining choice is the excellent JanRain library.

OK, the Jan rain library is not PHP 5.3 friendly. There are several warnings if you try included consumer test. The library also requires several extensions. To start you’d better read the README first and run the detect.php under its example directory. Fortunately, those warnings are easy to deal with and I won’t repeat them here.

$path = ini_get(’include_path’);
$path = APPLICATION_PATH . ‘/../library/openid-php’ . PATH_SEPARATOR . $path;
ini_set(’include_path’, $path);

require_once "Auth/OpenID/Consumer.php";
require_once "Auth/OpenID/FileStore.php";
require_once "Auth/OpenID/SReg.php";
require_once "Auth/OpenID/PAPE.php";

class OpenidController extends Zend_Controller_Action
{
  public function init()
  {
    $this->session = new Zend_Session_Namespace(’openid’);
    $this->store = $this->getFileStore();
    $this->consumer = new Auth_OpenID_Consumer($this->store);
  }
  
   /** for testing only. This is not necessary as openid_identifier
  *  is captured in the URL. */
  public function indexAction() 
  {
  }
  
  public function tryAction() 
  {
    $this->openid = $_GET['openid_identifier'];
    try {
      // Make sure the user entered something.
      if(strlen($this->openid) == 0) {
        throw new Exception(’OpenID is empty.’);
      }

      // Try to start an openid authentication.
      $auth_request = $this->consumer->begin($this->openid);

      if(!$auth_request) {
        throw new Exception("No Auth Request");
      }
      
      $sreg_request = Auth_OpenID_SRegRequest::build(
           // Required
           array(’nickname’),
           // Optional
           array(’fullname’, ‘email’));
    
      if ($sreg_request) {
        $auth_request->addExtension($sreg_request);
      }
      

       $redirect_url = $auth_request
        ->RedirectURL($this->getTrustRoot(),$this->getReturnTo());

      if (Auth_OpenID::isFailure($redirect_url)) {
        throw new Exception("Could not redirect to server: "
          . $redirect_url->message);
      }

    } catch (Exception $e) {
      $this->view->error = $e->getMessage();
      $this->render(’index’);
      return;
    }

    $this->_redirect($redirect_url);
  }
    
  private $session;
  private $store;
  private $consumer;
  private $openid;

  public function getFileStore() 
  {
    /**
     * This is where the example will store its OpenID information.
     * You should change this path if you want the example store to be
     * created elsewhere.  After you’re done playing with the example
     * script, you’ll have to remove this directory manually.
     */
    $store_path = null;
    if (function_exists(’sys_get_temp_dir’)) {
      $store_path = sys_get_temp_dir();
    }
    else {
      if (strpos(PHP_OS, ‘WIN’) === 0) {
        $store_path = $_ENV['TMP'];
        if (!isset($store_path)) {
          $dir = ‘C:\Windows\Temp’;
        }
      }
      else {
        $store_path = @$_ENV['TMPDIR'];
        if (!isset($store_path)) {
          $store_path = ‘/tmp’;
        }
      }
    }
    $store_path .= DIRECTORY_SEPARATOR . ‘_atlantis_openid’;
  
    if (!file_exists($store_path) &&
      !mkdir($store_path)) {
      print "Could not create the FileStore directory ‘$store_path’. ".
        " Please check the effective permissions.";
      exit(0);
    }
    $r = new Auth_OpenID_FileStore($store_path);

    return $r;
  }
  
  /**
   * When the identity provider is done having their
   * moment with the user they get returned to this action.
   * Here we look at the response status codes to decide
   * to if they were authenticated or not.
   */
  public function finishAction() 
  {
      $return_to = $this->getReturnTo();
      $response = $this->consumer->complete($return_to);
      
      if($response->status == Auth_OpenID_CANCEL) {
        $this->view->error = ‘Verification cancelled.’;
      } else if ($response->status == Auth_OpenID_FAILURE) {
        $this->view->error = "OpenID authentication failed: "
          . $response->message;
      } else if ($response->status == Auth_OpenID_SUCCESS) {
        $this->view->error =  "Success";
        
        $auth = Zend_Auth::getInstance();
        $adapter = new Application_Model_Account_OpenIDAdapter($response->identity_url);
        
        $result = $auth->authenticate($adapter);
        if ($result->isValid()) {
          $this->_redirect(’/');
          return;
        }
      }
    $this->_redirect(’/account/index’);
  }

  private function getScheme() 
  {
    $scheme = ‘http’;
    if (isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == ‘on’) {
      $scheme .= ’s’;
    }
    return $scheme;
  }

  private function getReturnTo() 
  {
    return sprintf("%s://%s/openid/finish",
             $this->getScheme(), $_SERVER['SERVER_NAME']);
  }

  private function getTrustRoot() 
  {
    return sprintf("%s://%s/", $this->getScheme(),
      $_SERVER['SERVER_NAME']);
  }  
  
}

The code starts with /openid/try action. It communicates with OpenID provider to obtain a URL that user will be redirected to. It also set the callback to /openid/finish. Note that I created class Application_Model_Account_OpenIDAdapter so that it fits Zend_Auth architecture. In reality, all it does is to write information to user account database and persist it to a storage in choice (such as session or cookie).

Overdesign case in Web UI

Today I went to a site that displays information on domains. I wanted to look at how we are doing so I entered Morovia in the search box. Quickly surprisingly I received a message

Morovia is an Invalid Extension.

difficult to understand uuuh? Obviously you have to put your full domain name - in this case, morovia.com. Otherwise it thinks morovia is the top domain name. But even so, why it is called “extension”? File names have extensions; while domain names have suffixes.

error-invalid-extension-search-domain

Nowadays smart phones are cheap. Android powered phones are around 100 dollars. It is not surprising that majority people now have smart phones - those with touch screen and have far more power than their predecessors. This phenomenon brings business opportunities that you as a business owner want to tap.

QR Code Image

QR Code Image


So what is QR Code?

A QR Code is a 2D barcode that can be scanned by smart phone’s camera. It is capable of encoding large amount of text; however most QR codes encode a few dozen characters. QR Code becomes increasingly popular because smart phones now have decoder programs that read the barcode and act on the content it reads.

So what is the big deal for that? It turns out that QR Code offers a convenient way to encode key information - such as your web site address, email and so on. A smart phone owner can capture the info to his phone by just scanning the QR Code.

You certainly want your web site gets more visits - but how? If you run a restaurant, you can print a QR Code at the bottom of receipt, or in news paper… people who are interest just scan the QR code and visit your web site.

Some more ideas:

1. QR Code on Business Card. There is a popular format called MECARD, which allows contact info to be encoded into a QR Code. A smart phone user scans the barcode and put your contact into his address book. Hey if you are in real estate agent, insurance broker or industry that you’d like everyone to remember you, QR Code is a must.

2. Product Label. If you are a manufacturer it is time to add a QR Code with your web site encoded on the product label. Customers who bought your stuff may scan the barcode and visit your web site. Even more, you can print something like - scan this QR code to get a 10% off coupon.

3. Promotions, Discounts and Coupons. The idea here is to get the user to visit your web site and receive the discount. If you just print a coupon barcode on the newspaper your web site won’t get visited. It is also easier to track users through your web site.

4. E-commerce. QR Code encodes a URL with extra parameters - and users can only see them when they scan the barcode. So you can easily offer different discounts to different audience.

QR code can encode many information: such as web site URL, E-mail address and contact info. This Morovia page lists the common usage in mobile industry. Even better, there is an online QR code generator that create QR codes for free.

If you are looking a solution to add QR Code to Word documents, we’d like to recommend Morovia’s excellent product QR Code Fonts & Encoder 5. With this word addin, creating a QRcode just takes two steps - highlight and convert; all can be done in 1 minute.