Sourcing dojo from AOL's CDN under Zend Framework

This implementation uses a default layout. To set the path and name of the layout (default.phtml), the application.ini file was configured like so:

configs/application.ini

resources.layout[] =
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
resources.layout.layout = "default"

Bootstrap.php adds dojo to thel helper path for the view in _initView. The locale is set up as well as the translation.

Bootstrap.php

protected function _initView()
    {
        Zend_Session::start();
        $session=new Zend_Session_Namespace('global');
        $options=$this->getOptions();

        $locale = new Zend_Locale(Zend_Locale::BROWSER,TRUE);
        $session->strLocale=$locale->toString();
        Zend_Registry::set('Zend_Locale', $locale);

        $language_path=$options['resources']['locale']['translation']['path'];
        $translate = new Zend_Translate(array('adapter'=>'gettext',
                'content'=>$language_path,
                'scan' => Zend_Translate::LOCALE_DIRECTORY,
                'locale'=>$locale->toString()));
        Zend_Registry::set('Zend_Translate', $translate);

        $view = new Zend_View();
        $view->doctype('XHTML1_STRICT');
        $view->headLink()->appendStylesheet('/css/base.css')
            ->appendStylesheet('/css/color.css');

        $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
        $viewRenderer->setView($view);

        $view->addHelperPath('Zend/Dojo/View/Helper/', 'Zend_Dojo_View_Helper');
        Zend_Dojo_View_Helper_Dojo::setUseDeclarative();

        $view->strLocale=$session->strLocale;

        return $view;
    }

In the controller for the form, dojo is enabled. This way, the layout only includes dojo if the form or page requires it.

        $this->view->form = $form;
        $this->view->dojo()->enable();
        if ($this->getRequest()->isPost())

In the layout, the final dojo configuration is done, if dojo is enabled.

application/layouts/scripts/default.phtml


<?php 
// application/layouts/scripts/default.phtml

echo $this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head>  
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <?php echo $this->headTitle() ?>
    <?php echo $this->headMeta() ?>
    <?php echo $this->headLink() ?>
    <?php echo $this->headStyle() ?>
<?php if ($this->dojo()->isEnabled()){
        $this->dojo()
            ->setCdnBase(Zend_Dojo::CDN_BASE_AOL)
            ->setCdnVersion('1.5')
            ->setCdnDojoPath(Zend_Dojo::CDN_DOJO_PATH_AOL);
        $this->dojo()
            ->setDjConfigOption('parseOnLoad', true)
            ->setDjConfigOption('locale',$this->strLocale)
            ->setDjConfigOption('cdnbase',Zend_Dojo::CDN_BASE_AOL)
            ->setDjConfigOption('cdnversion','1.5')
            ->setDjConfigOption('cdndojopath',Zend_Dojo::CDN_DOJO_PATH_AOL)
            ->addStyleSheetModule('dijit.themes.tundra')
            ->requireModule('dijit.form.Form')
            ->requireModule('dijit.form.ValidationTextBox')
            ->requireModule('dijit.form.TextBox');
            echo $this->dojo();
   }
?>

PHP Base Class Implementation with Iterator

This is a class definition for a base class which can be extended.

Features

  • Attributes are defined dynamically
  • Iteration is implemented, to allow the use of foreach
  • Attribute validation is included
  • Uses array_fill_keys if it is available, otherwise gracefully degrades to use a foreach loop
  • Allows attribute assignment with an associative array

Base Class Definition


require_once 'include/common.php';

class Base Implements Iterator
{
        /**      Location for overloaded data.  */
        protected $data = array();

        public function __construct($attribute_names=null,$attribute_values=null)
        {
                if ($attribute_names!==null)
                {
                        if (function_exists(array_fill_keys))
                                $this->data=array_fill_keys($attribute_names,'');
                        else
                                foreach ($attribute_names as $v)
                                        $this->data[$v]='';
                        if ($attribute_values!==null)
                                foreach ($attribute_values as $k => $v)
                                        $this->$k=$v;
                }
                else
                        if (get_class($this)!=='Base')
                                halt(FAIL_CLASS_HAS_NO_ATTRIBUTES,get_class($this).' class has no attributes');
        }

        public function __set($name,$value)
        {
                if (array_key_exists($name,$this->data))
                        $this->data[$name]=$value;
                else
                        halt(FAIL_INVALID_ATTRIBUTE,get_class($this).' invalid attribute '.$name);
        }

        public function __get($name)
        {
                if (array_key_exists($name,$this->data))
                        return($this->data[$name]);
                else
                        return null;
        }

        public function __isset($name)
        {
                return isset($this->data[$name]);
        }
        public function rewind()
        {
                return reset($this->data);
        }

        public function current()
        {
                return current($this->data);
        }

        public function key()
        {
                return key($this->data);
        }

        public function next()
        {
                return next($this->data);
        }

        public function valid()
        {
                return current($this->data)!==false;
        }


        public function __destruct()
        {
        }
}

Extension Class

class User extends Base
{
        public function __construct($aArgs=null)
        {
                bsBase::__construct(array(
                        'userID','roleName','userName',
                        'firstName','middleName','lastName','loginName',
                        'password','email','contactPhone'),$aArgs);
        }

        function __destruct()
        {
        }
}

Object Instantiation


/* Create a new user, with the userID set to 1 */
$oUser=new User(array('userID'=>1));
$oUser->firstName='John';
foreach ($oUser as $k => $v)
  echo $k.' -> '.$v.PHP_EOL;

This post courtesy of Lyrix, Inc. / Mobiso

dijit ValidationTextBox Custom Validator

The dijit ValidationTextBox widget is an excellent way to help users enter valid data. Recently, I had a very long and complex regular expression that caused performance issues when the data was typed into the input. To improve performance, I used a custom validator (http://docs.dojocampus.org/dijit/form/ValidationTextBox-tricks).


var dijits=Array('sInboundFormat','sOutboundFormat');
var regexps=Array(/^sip:[\w]+@[\w\.]$/,/^sip:[\w]+@[\w\.]$/);

dojo.addOnLoad(function()
{
        var i,ld=dijits.length;
        for (i=0;i<ld;i++)
        {
                /* Store the regular expression for the input */
                dijit.byId(dijits[i]).cRegExp=regexps[i];
                /* The bValid flag stores the current state of the input */
                dijit.byId(dijits[i]).bValid=true;
                dijit.byId(dijits[i]).validator=function (value,constraints) {
                        /* Determine where the focus is */
                        var d=dijit.getFocus();
                        /* If the focus is on the save button */
                        if ((d!=null) && (d.node!=null) && (d.node.id=='btnSave'))
                        {
                            if (dojo.trim(this.value)!='')
                            {
                                /* Set the bValid flag */
                                this.bValid=this.cRegExp.test(this.value);
                                /* Update the error icon on the input */
                                if (!this.bValid)
                                        dojo.addClass(this.domNode,'dijitError');
                                else
                                        dojo.removeClass(this.domNode,'dijitError');
                            }
                            else
                                this.bValid=!this.required;
                        }
                        /* Return the input state (valid or not) */
                        return this.bValid;
                };
        }
});

This code adds an attribute to the widget, bValid. bValid is initialized to true, and updated after the input is validated. The performance gain is realized by testing the focus and only running the test if the user has just clicked ‘Save’.

Since the validation is not performed as the data is entered, it’s not a real-time validation, however, the input does include the warning icon after the validation cycle, to help the user quickly find errors.

This post courtesy of Lyrix, Inc. / Mobiso

An Excellent Dialup ISP - US

As noted in the previous post, a free Juno account grants you access to juno.com, including their webmail.

Juno requires that even people that subscribe to their service use their software to connect to the Internet.

Unfortunately, their software isn’t available for Linux.

An excellent alternative is http://dialup4less.com. The rates are fair, the service is great, and the connection is fast. They have access numbers in most states, if not all.

Ubuntu 9.04 - USB Dialup - Juno - Connect

My Mom uses Juno’s dialup service to connect to the Internet and for email. Her HP laptop (running Windows) was infected with something, and had really become unusable, it was so slow.

I took it home where my most valuable tool is a high-speed Internet connection.

After many tries, this is the general sequence of operations that worked.

  1. Install Ubuntu 9.04. Other versions may work, I chose this because Linuxant had drivers to support the internal modem. It’s nice.
  2. Run the upgrades offered.
  3. Restart
  4. The internal modem just wouldn’t work, so I bought an external USB modem from Best Buy. Zoom Modem, Model 3095.
  5. Followed the installation instructions and found that this laptop isn’t supported (it’s an x86_64). Used the link above and built the driver from the source. Many thanks to Linuxant.com.
  6. Added the user to dip and dialout groups
  7. Installed Gnome PPP, and Network
  8. Use sudo wvdialconf to configure wvdial
  9. Manually edited /etc/wvdial.conf to add in the Juno phone numbers, username and password
  10. Restart
  11. Tested the connection using wvdial, it worked. Then tested with Gnome PPP, it worked. Finally, used Network and PPP to connect, and browsed to juno.com
  12. Since I have a free account, Juno runs in a limited mode, but it is running. If you have a paid Juno account, it still won’t work with Linux. I recommend http://dialup4less.com as an alternate ISP.

Ubuntu is really nice to work with.