Archive for 'Programming'

Now the contact information can encode Unicode characters with our free QR code business card maker. Previously characters outside ISO8859-1 are filtered. Now they show up correctly.

QR Business Card with Unicode

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

With Morovia Barcode ActiveX 3, it is easy to bulk generate barcode images. The following 10 lines of perl code just demonstrate how easy it is.

use Win32::OLE;
my $object = Win32::OLE->new(’Morovia.BarcodeActivex’, ”);
$object->{”Symbology”} = 8; #UPC-A symbology
$object->{”ShowComment”} = 0;
$object->{”BarHeight”}=1000;

for(my $number=0; $number<=999; $number++)
{
my $text_number = sprintf(”%03d”, $number);
$object->{”message”} = “81058201″ . $text_number;

print(”exporting image $text_number.\n”);

$object->ExportImage($object->{”message”} . “.jpg”, 1);
}

my $result = `zip all-images.zip *.jpg`;

The code above generates UPC-A barcode images for numbers 81058201xxx where xxx is from 000 to 999. At the end, the code calls zip command to zip all the images files into zip.