Location: PHPKode > scripts > Meta Builder > includes/builder/FormElement.php
<?php

/*
 * BuilderFormElement
 *
 * Copyright(c) 2010, Thomas Shone
 * Licensed under the Creative Commons Attribution 3.0 Unported License.
 * http://www.shone.co.za
 *
 * Constructs forms elements from meta data
 */

class BuilderFormElement
{
    private $aMeta;
    private $aData;
    private $aClasses;
    private $aExtras;
    private $aAttributes;

    public function Build($aMeta, $aData = array())
    {
        $this->aMeta        = $aMeta;
        $this->aData        = $aData;
        $this->aClasses     = array();
        $this->aExtras      = array();
        $this->aAttributes  = array();

        $aMethods = get_class_methods(__CLASS__);
        $sRenderFunction = 'Render' . ucwords($aMeta['type']);
        if (in_array($sRenderFunction, $aMethods))
        {
            $this->___CheckMeta();
            $this->___ConstructAttributes();
            $this->___ConstructExtras();
            $this->___ConstructClasses();
            return $this->$sRenderFunction();
        }
    }

    private function ___GetData()
    {
        // Don't attempt to set data for the following elements
        $aExcludeList = array('submit');
        if (in_array($this->aMeta['type'], $aExcludeList))
        {
            return $this->aMeta['value'];
        }

        // Look up post specific input match
        $mValue = Input::GetPost($this->aMeta['name']);
        if ($mValue)
        {
            return $mValue;
        }

        // If nothing there, look up non-post specific input match
        $mValue = Input::Get($this->aMeta['name']);
        if ($mValue)
        {
            return $mValue;
        }

        // Look up data passed
        if (!empty($this->aData[$this->aMeta['name']]))
        {
            return $this->aData[$this->aMeta['name']];
        }


        if (!empty($this->aMeta['value']))
        {
            return $this->aMeta['value'];
        }
        return '';
    }

    private function ___CheckMeta()
    {
        if (empty($this->aMeta['name']))
        {
            throw new Exception('Name Required.');
        }
        if (empty($this->aMeta['type']))
        {
            throw new Exception('Type Required.');
        }

        $this->aMeta['value'] = $this->___GetData();
    }

    private function ___ConstructAttributes()
    {
        if (empty($this->aMeta['id']))
        {
            $this->aMeta['id'] = $this->aMeta['name'];
        }

        // Check validation for attributes
        !empty($this->aMeta['validation']['length']['max']) && $this->aAttributes['maxlength']  = $this->aMeta['validation']['length']['max'];
        !empty($this->aMeta['validation']['length']['min']) && $this->aAttributes['size']       = $this->aMeta['validation']['length']['min'];

        $aFields = array('type', 'name', 'id', 'value', 'cols', 'rows', 'class', 'size', 'maxlength', 'hint');
        foreach ($aFields as $sField)
        {
            if (!empty($this->aMeta[$sField]))
            {
                switch ($sField)
                {
                    case 'name':
                        $this->aAttributes[$sField] = 'input['. $this->aMeta[$sField] .']';
                        break;

                    case 'hint':
                        $this->aAttributes['rel'] = 'hint:'. $this->aMeta[$sField];

                    default:
                        $this->aAttributes[$sField] = $this->aMeta[$sField];
                        break;
                }
            }
        }
    }

    private function ___ConstructExtras()
    {
        if (!empty($this->aMeta['image']))
        {
            $this->aExtras[] = '<img id="'. $this->aMeta['name'] .'-image" src="'. BuildUrl('html/images/'. $this->aMeta['image']) .'" />';
        }

        if (!empty($this->aMeta['description']))
        {
            $this->aExtras[] = '<span id="'. $this->aMeta['name'] .'-description" class="description">'. $this->aMeta['description'] .'</span>';
        }

        $aInlineErrors = Messages::GetInlineErrors($this->aMeta['name']);
        if ($aInlineErrors && count($aInlineErrors))
        {
            $this->aExtras[] = '<span class="message-error message-error-inline">'. implode('<br/>', $aInlineErrors) .'</span>';
        }
    }

    private function ___ConstructClasses()
    {
        if ($this->aMeta['type'] == 'submit')
        {
            $this->aClasses[] = 'submit';
        }
        if (!empty($this->aMeta['render']['class']))
        {
            $this->aClasses[] = $this->aMeta['render']['class'];
        }
        // Build Validation
        if (!empty($this->aMeta['validation']))
        {
            $aFields = array();
            $aFields[] = !empty($this->aMeta['validation']['required']) ? 'required' : 'optional';
            if (!empty($this->aMeta['validation']['match']))
            {
                switch ($this->aMeta['validation']['match'])
                {
                    case 'alphanumeric':
                        $aFields[] = 'custom[noSpecialCaracters]';
                        break;
                    case 'alpha':
                        $aFields[] = 'custom[onlyLetter]';
                        break;
                    case 'numeric':
                        $aFields[] = 'custom[onlyNumber]';
                        break;
                    case 'date':
                        $aFields[] = 'custom[date]';
                        break;
                    case 'email':
                        $aFields[] = 'custom[email]';
                        break;
                    case 'telephone':
                        $aFields[] = 'custom[telephone]';
                        break;
                    case 'url':
                        $aFields[] = 'custom[url]';
                        break;
                    case 'ajax':
                        $aFields[] = 'ajax[' . $this->aMeta['validation']['type'] . ']';
                        break;
                    default:
                        break;
                }
            }

            if (!empty($this->aMeta['validation']['confirm']))
            {
                $aFields[] = 'confirm['. $this->aMeta['validation']['confirm'] .']';
            }

            if (
                !empty($this->aMeta['validation']['length']['min']) &&
                !empty($this->aMeta['validation']['length']['max'])
                )
            {
                $aFields[] = 'length[' . $this->aMeta['validation']['length']['min'] . ',' . $this->aMeta['validation']['length']['max'] . ']';
            }

            $this->aClasses[] = 'validate[' . implode(',', $aFields) .']';
        }
    }

    private function RenderAttributes()
    {
        $sResult = '';
        foreach ($this->aAttributes as $sKey => $sValue)
        {
             $sResult .= ' ' . $sKey . '="' . $sValue . '"';
        }
        return $sResult;
    }

    private function RenderExtras()
    {
        return implode(' ', $this->aExtras);
    }

    private function RenderClasses()
    {
        return implode(' ', $this->aClasses);
    }

    private function RenderLabel()
    {
        return $this->aMeta['label'];
    }

    private function RenderBasic()
    {
        return "\n\t" . '<input' . $this->RenderAttributes() . ' class="' . $this->RenderClasses() . '" /> ' . $this->RenderExtras();
    }

    private function RenderText()
    {
        return $this->RenderBasic();
    }

    private function RenderTextarea()
    {
        $sValue = '';
        if (!empty($this->aAttributes['value']))
        {
            $sValue = $this->aAttributes['value'];
            unset($this->aAttributes['value']);
        }
        return "\n\t" . '<textarea' . $this->RenderAttributes() . ' class="' . $this->RenderClasses() . '" />' . $sValue . '</textarea> ' . $this->RenderExtras();
    }

    private function RenderPassword()
    {
        return $this->RenderBasic();
    }

    private function RenderSubmit()
    {
        return $this->RenderBasic();
    }

    private function RenderFile()
    {
        return $this->RenderBasic();
    }

    private function RenderCheckbox()
    {
        return $this->RenderBasic();
    }

    private function RenderHidden()
    {
        return $this->RenderBasic();
    }

    private function RenderRadioList()
    {
        $sResult = '';

        $sId = $this->aAttributes['id'];
        foreach ($this->aMeta['list'] as $aEntry)
        {
            $sName = !empty($aEntry['name'])
                        ? $aEntry['name']
                        : $aEntry['value'];

            unset($this->aAttributes['checked']);
            $this->aAttributes['value'] = $aEntry['value'];
            $this->aAttributes['id'] = $sId .'-'. $sName;

            $sLabel = $sName;
            if (!empty($aEntry['image']))
            {
                $sLabel = '<img src="'. BuildUrl('html/images/'. $aEntry['image']) .'" /> '. $sLabel;
            }
            if (!empty($this->aMeta['value']) && $aEntry['value'] == $this->aMeta['value'])
            {
                $this->aAttributes['checked'] = 'true';
            }

            $sResult .= '<input '. $this->RenderAttributes() .'><label for="'. $this->aAttributes['id'] .'">'. $sLabel .'</label><br/>' ."\n";
        }

        return $sResult;
    }

    private function RenderCheckList()
    {
        return $this->RenderRadioList();
    }

    private function RenderSelectList()
    {
        $sResult = '';

        $sResult .= '<select '. $this->RenderAttributes() .'>' ."\n";
        if (!empty($this->aMeta['list']))
        {
            foreach ($this->aMeta['list'] as $aEntry)
            {
                $sLabel = !empty($aEntry['name'])
                            ? $aEntry['name']
                            : $aEntry['value'];

                if (!empty($aEntry['image']))
                {
                    $sLabel = '<img src="/html/images/'. $aEntry['image'] .'" /> '. $sLabel;
                }

                $sResult .= '<option value="'. $aEntry['value'] .'">'. $sLabel .'</option>' ."\n";
            }
        }
        $sResult .= '</select>' ."\n";

        return $sResult;
    }

    private function RenderList()
    {
        $sResult = '';
        if (!empty($this->aMeta['script']))
        {
            $sResult .= "<script>
$(document).ready(function()
{
    $.getJSON('" . BuildUrl($this->aMeta['script']) . "',
    function(data)
    {
        $.each(data, function(i,item)
        {
            $('#" . $this->aMeta['id'] . "').append('<option value=\"' + item.value + '\" ' + (\"". $this->aMeta['value'] ."\" == item.value ? 'selected=\"true\"' : '') + '>' + item.name + '</option>');
        });
    });
});
        </script>";
        }

        switch ($this->aMeta['render-mode'])
        {
            case 'radio':
                $this->aAttributes['type'] = 'radio';
                $sResult .= $this->RenderRadioList();
                break;
            case 'checkbox':
                $this->aAttributes['type'] = 'checkbox';
                $sResult .= $this->RenderCheckList();
                break;
            case 'select':
            default:
                $sResult .= $this->RenderSelectList();
                break;
        }

        return $sResult . $this->RenderExtras();;
    }


    // TODO: Implement these
/*    private function RenderTags()
    {
        $sResult  = '<input '. $this->RenderAttributes() .'>' . $this->RenderExtras() ."\n";
        $sResult .= "<script>
$(document).ready(function() {
    $('#" . $this->aMeta['id'] . "').tokenInput('" . $this->aMeta['script'] . "', {});
});
        </script>";

        return $sResult;
    }

    private function RenderCaptcha()
    {
        $sResult  = '<img src="' . BuildUrl('captcha/index') . '?sid=' . md5(uniqid(time())) . '"><br/>';
        $sResult .= $this->RenderBasic();
        return $sResult;
    }*/
}
Return current item: Meta Builder