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.

Hack Attack

For the last year or so, I have a site that sends me an email listing all the new and modified files on the server.

This morning, these entries caught my eye:

/var/www/html/
/var/www/html/c99.php

The c99 file was not supposed to be on the server.

Listing the /var/www/html directory, I found:

-rw-r–r– 1 nobody nobody 7293 Aug 1 04:58 (at sign).php
-rw-r–r– 1 nobody nobody 162032 Jul 31 05:57 c99.php
-rw-r–r– 1 nobody nobody 0 May 23 01:36 index.html
-rw-r–r– 1 nobody nobody 44283 May 23 01:36 Dont.Touch.php

I went back in my email Inbox, and found that the May 23 email was never received - cron had stopped on the server, and a ticket was sent to restart it.

The hosting company recommended I update some file and directory permissions, which I did, with the following commands:

find -type f | xargs chmod 644
find -type d | xargs chmod 755

These set permissions for a files to 644, and all directories to 755.

Tarred up the files and sent them to the hosting company, along with some notes.

On the bright side - nothing was lost, and the cleanup was pretty straightforward.

The error log showed execution attempts, which failed, and that IP address has been blocked.

Hack was not on this server.