使用输入对象从xml解析Form,保持数据完整性

时间:2013-04-07 11:51:09

标签: php xml forms oop dry

我正在创建一个系统表单来构建一个处理xml的表单。 表单布局几乎相同,因此根据url,我将加载一个不同的xml,它将生成不同的表单。

我使用了3个不同的类:

  • 表单管理所有表单信息(操作,enctype,文件的上传目录),值(如果在更新中),语言和输入创建
  • 输入管理有关输入(名称,ID,...)
  • 的所有内容
  • 语言管理标签

当我创建Form obj时,我创建了语言类的实例(输入标签是Language实例键),从db获取值并解析XML以创建输入作为Input类实例(在构造函数中传递输入xml对象)。 Form类在创建输入

时的摘录
            if(count($obj->input)):
                foreach($obj->input as $input):                             
                    $Input = new Input($input);
                    $val = !empty($this->arValues['normal'][(string)$Input->getname()]) ? $this->arValues['normal'][(string)$Input->getname()] : '';
                    $Input->setvalue($val);
                    $label = !empty($input['label']) && !empty($this->Language->getTranslation((string)$input['label'])) ? $this->Language->getTranslation((string)$input['label']) : '';
                    $Input->setlabel($label);
                    $Input->setlgTag($lgTag);
                    $this->arInputs[(string)$Input->getname()] = $Input;
                endforeach;
            endif;

Xml输入可以是:

    <input type="text" label="label_name" name="name" ...></input>

但也是:

    <input type="image" label="image_name" name="img" usecaption="true" ...></input>

在第一种情况下没问题,我得到了我的意见; 在第二种情况下,情况更棘手: - 我在Form中定义了文件上传目录,但是对于输入值我也需要它在输入实例中(这很简单,但是当我在Input类中定义输入类型时,我会填充一个值,即使不需要它也是如此) ) - 基于属性'usecaption'我想为关联标题创建一个输入类型文本到图像:实际上我将在一个xml输入(类型图像)中有2个html输入(类型文件和类型文本)和我丢失了数据,因为值和语言在Form中被定义。

我想过在输入中使用Form实例,但是由于在Form类中定义了Input实例,可能会出现递归问题,而且这不是DRY。

我的问题是: 我如何通过输入表格形式实施和重新使用特定数据?

任何答案都表示赞赏...... 当然,我错过了一些东西,但现在我正在循环......

    #######################################################
    #
    #   class Form
    #
    #   Form management
    #
    #######################################################

    class Form {

private $xmlObj;        // xml object used in form construction
private $arInputs;      // all the input objects stored

private $Translations;  // will contain instance of Translations Class
private $ODB;           // class for managing db
private $_ID;           // ID of the Elements (if any)
private $tab_name;      // table name
private $UploadDir;     // upload dir for files

// form properties
public $action  = '';
public $method  = 'post';
public $enctype = '';

public $arValues = array(); // array for all form values

private $strForm;           // string that will contain form html

/*
 *  __construct
 *
 *  Get xmlObj, translations and element id
*/
public function __construct($xmlObj = NULL, $arTrads = array(), $_ID = 0){

    $this->xmlObj   = $xmlObj;      
    $this->Translations     = TranslationsManager::getInstance();

    $this->ODB = DBObject::getInstance();
    $this->_ID = $_ID;

    $this->tab_name     = !empty($xmlObj['tab_name']) ? $xmlObj['tab_name'] : '';
    $this->UploadDir    = !empty($xmlObj['upload_dir']) ? $xmlObj['upload_dir'] : '';
    $this->action       = !empty($xmlObj['action']) ? $xmlObj['action'] : '';
    $this->method       = !empty($xmlObj['method']) ? $xmlObj['method'] : 'post';
    $this->enctype      = !empty($xmlObj['enctype']) ? $xmlObj['enctype'] : '';

}


/*
 *  SetupInputs
 *
 *  I populate array Input
 *
*/
public function SetupInputs(){


    if(count($this->input)):
        foreach($this->input as $input):                                
            $Input = new Input($input);     // creo l'oggetto input

        endforeach;
    endif;

}   


/*
 *  HtmlForm
 *
 *  I echo The form Input
 *
*/
public function HtmlForm(){

    $this->strForm = '';

    if(count($this->xmlObj->input)):
        foreach($this->xmlObj->input as $input):
            $this->strForm .= $this->arInputs[(string)$input['name']]->htmlIt();
        endforeach;
    endif;

    return $this->strForm;

}

}

    #######################################################
    #
    #   class Input
    #
    #   Input management
    #
    #######################################################

    class Input {

private $arAttributes = array();            // Input attributes
private $arOptions = array();               // Input options (to use in input like select, radio, checkbox)
private $strInput;                          // html


/*
 *  __construct
 *
 *  Imposto tutti gli attributi dell'input
*/
public function __construct($inputobj = NULL){  // if I don't have any xml obj as parameter, I just create the input object

    if($inputobj !== NULL && is_object($inputobj) !== false):

        // get attributes if any
        if(count($inputobj->attributes())):                                 
            foreach($inputobj->attributes() as $key => $val):
                $this->arAttributes[(string)$key] = (string)$val;
            endforeach;
        endif;

        // I any option
        if(count($inputobj->children())):
            foreach($inputobj->children() as $v):
                $this->addOption($v);
            endforeach;
        endif;

        // I define id and html of required field
        if($this->getAttribute('id') === false && $this->getAttribute('name') !== false) $this->setAttribute('id', $this->getAttribute('name')); // If not specific id I usa name
        $this->getAttribute('required') !== false && $this->getAttribute('required') > 0 ? $this->setAttribute('html_required', '*') : $this->setAttribute('html_required', '');

    endif;

}

/*
 *  OVERLOADING
 *
 *  I use to get and set properties from outside
*/
public function __call($prop, $v){

    $attr = substr($prop, 3);
    $method = substr($prop, 0,  3);

    switch($method):
        case 'set': return $this->setAttribute($attr, $v[0]); break;
        case 'get': return $this->getAttribute($attr); break;
    endswitch;

}


/*
 *  getAttribute - setattribute
 *
 *  
 *
*/
private function getAttribute($attr){       
    return array_key_exists((string)$attr, $this->arAttributes) !== false ? $this->arAttributes[(string)$attr] : false;
}

private function setAttribute($attr, $value){
    $this->arAttributes[(string)$attr] = $value;
    return true;
}


/*
 *  addOption
 *
 *  add an option to input checkbox, radio o select
*/
public function addOption($Options){    
    $this->arOptions[] = $Options;
}


/*
 *  htmlIt
 *
 *  generate html
 *
*/
public function htmlIt(){

    // **************************************************************** ISSUE
    // I'd like to get the translation using attribute label as parameter: html_label is the correct translation
    $this->getAttribute('label') !== false  
        ? $this->setAttribute('html_label', $this->Form->Translations->getTranslations((string)$this->getAttribute('label'))) // <-- HERE I WOULD LIKE TO ACCESS THE Trasnlations INSTANCE IN FORM
        : $this->setAttribute('html_label', '');    // ridefinisco la label dell'input sull base della traduzione

    switch($this->getAttribute('type')):
        case 'texteditor': 
            return $this->texteditor();
            break;

        case 'textarea': 
            return $this->textarea();
            break;

        case 'radio':
            return $this->radio();
            break;

        case 'img':
            return $this->img();
            break;

        case 'file':
            return $this->file();
            break;

        default: 
            return $this->text();
    endswitch;

}


/*
 *
 *  I CREATE DIFFERENT INPUT TYPE
 *
 */

private function text(){

    return '    <label'.$this->getAttribute('style').'>'.$this->getAttribute('html_label').$this->getAttribute('html_required').'
                    <input type="text" name="'.$this->getAttribute('name').'" id="'.$this->getAttribute('id').'" value="'.$this->getAttribute('value').'">
                </label>'."\n";

}


private function texteditor(){

    return '    <label'.$this->getAttribute('style').'>'.$this->getAttribute('html_label').$this->getAttribute('html_required').'
                    <textarea name="'.$this->getAttribute('name').'" id="'.$this->getAttribute('id').'" cols="20" rows="5">'.$this->getAttribute('value').'</textarea>
                </label>
                <script type="text/javascript">
                //<!--
                    CKEDITOR.replace("'.$this->getAttribute('id').'")
                //-->
                </script>
                '."\n";
}


private function textarea(){
    return '    <label'.$this->getAttribute('style').'>'.$this->getAttribute('label').$this->getAttribute('html_required').'
                    <textarea name="'.$this->getAttribute('name').'" id="'.$this->getAttribute('id').'" cols="20" rows="5">'.$this->getAttribute('value').'</textarea>
                </label>'."\n";
}


private function radio(){

    if(!$this->arOptions || !count($this->arOptions)) return false;     // if not any option

    $strInput = '   <div class="radio_input"><p>'.$this->getAttribute('html_label').$this->getAttribute('html_required').'</p>'."\n";

    foreach($this->arOptions as $Option):

        $checked = $this->getAttribute('value') && $this->getAttribute('value') == $Option['value'] ? true : false;
        $optLabel = $Option['label'] && strlen($this->Form->Translations->getTranslations($Option['label']))    
            ? $this->Form->Translations->getTranslations($Option['label'])   // <-- HERE I WOULD LIKE TO ACCESS THE Translations INSTANCE IN FORM
            : '';
        if($checked == true):
            $strInput .= '  
                            <label class="button label_checked">
                                <input type="radio" name="'.$this->getAttribute('name').'" id="'.$Option['id'].$lgSuff.'" value="'.$Option['value'].'" checked>
                                '.$optLabel.'
                            </label>'."\n";
        else:
            $strInput .= '  
                            <label class="button">
                                <input type="radio" name="'.$this->getAttribute('name').'" id="'.$Option['id'].$lgSuff.'" value="'.$Option['value'].'">
                                '.$optLabel.'
                            </label>'."\n";             
        endif;


    endforeach;

    $strInput .= '  </div>'."\n";
    return $strInput;

}


private function img(){

    $strFileName = $this->getAttribute('value') !== false && strlen($this->getAttribute('value')) > 0 
        // ***** I would like to access the Form upload_dir and id
        ? '<p class="filename"><img src="/file_upload/'.$this->Form->upload_dir.'/'.$this->Form->_ID.'/S_'.$this->getAttribute('value').'"> - 
            <label class="clear_file"><input type="checkbox" name="remove_'.$this->getAttribute('name').'" id="remove_'.$this->getAttribute('id').'">'.$this->Form->Translations->getTranslations('cancella_file').'</label></p>' 
        : '';
    $strInput = '   <div class="input_file">'."\n";
    $strInput .=        $strFileName;
    $strInput .=        '<label class="file_label">'.$this->getAttribute('html_label').$this->getAttribute('html_required').'<br>
                        <input type="file" name="'.$this->getAttribute('name').'" id="'.$this->getAttribute('id').'">
                    </label>'."\n";
    $strInput .= '  </div>'."\n";
    return $strInput;

}


private function file(){

    $strFileName = $this->getAttribute('value') !== false && strlen($this->getAttribute('value'))
                ? '<p class="filename">['.$this->getAttribute('value').'] - <label class="clear_file"><input type="checkbox" name="remove_'.$this->getAttribute('name').'" id="remove_'.$this->getAttribute('id').'">'.
                    $this->Form->Translations->getTranslations('cancella_file').'</label></p>' 
                : '';
    $strInput = '   <div class="input_file">'."\n";
    $strInput .=        $strFileName;
    $strInput .=        '<label class="file_label">'.$this->getAttribute('html_label').$this->getAttribute('html_required').'<br>
                            <input type="file" name="'.$this->getAttribute('name').'" id="'.$this->getAttribute('id').'">
                    </label>'."\n";
    if($this->getAttribute('caption') !== false):

        /************************************************************/
        // BIG ISSUE: CREATE INPUT INSIDE ANOTHER
        // I need to access Form values
        $v = !empty($this->Form->arValues[$this->getAttribute('name').'_caption']) ? $this->Form->arValues[$this->getAttribute('name').'_caption'] : '';

        $caption = new Input();
        $caption->setAttribute('type', 'text');
        $caption->setAttribute('name', (string)$this->getAttribute('name').'_caption');
        $caption->setAttribute('id', (string)$this->getAttribute('id').'_caption');
        $caption->setAttribute('label', $this->Form->Translations->getTranslations((string)$this->getAttribute('caption')));
        $strInput .= $caption->htmlIt();

    endif;
    $strInput .= '  </div>'."\n";
    return $strInput;

}

}

AND XML

<?xml version="1.0" encoding="utf-8"?>
    <form tab_name="news" upload_dir="news" enctype="multipart/form-data" action="actionfile.php">

<input type="text"      label="title"           name="title"></input>
<input type="textarea"  label="description"     name="description"></input>
<input type="img"       label="img_1"           name="img_1" prefix="S_,M_" width="300,500" height="300,0" crop_image="Y,N"></input>

    </form>

0 个答案:

没有答案