Advertisement
Guest User

Form Library - Input Fields

a guest
Jul 6th, 2011
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 33.37 KB | None | 0 0
  1. <?php
  2.  
  3. // This is used in the set_field_as_select_plant() method.
  4. // Indicates than an "All Plants" option should be added to drop-down.
  5. define (ALLPLANTS_OPTION, true);
  6.  
  7. class input_field
  8. {
  9.  
  10.     /*
  11.     File:       input_field.class.php
  12.     Developer:  Shane Harter
  13.     Created:    Apr 26, 2008
  14.     Version:    1.0
  15.    
  16.     Description:
  17.     ---------------------------------------------------------------------------------------
  18.     Represents an html input field on a webform class
  19.  
  20.     Instructions:
  21.     ---------------------------------------------------------------------------------------
  22.     Instantiate and pass-in the field_name, and a reference to the webform object that owns the field
  23.     The webform object is expected to be bound to a data_model object.
  24.  
  25.     Once constructed, you must define the html attached to the $field. You can do it manually, passing HTML for the input directly
  26.     into set_field().
  27.  
  28.     Or you can use pre-constructed tempalates in the form of the dozen set_field_as_*() methods. In many cases, these auto methods will
  29.     be perfectly adequate.
  30.  
  31.     After the field is set, next set the $label. You can set HTML directly to the $this->label property, or you can use the label-builder
  32.     by passing the label text to set_label(). This will build a <label> tag for you automatically.
  33.  
  34.     The final step is just assigning the $order that the field should be displayed in relation to other $field objects on the webform.
  35.  
  36.     Dependencies:
  37.     ----------------------------------------------------------------------------------------
  38.     libFormat       v1.0
  39.     libValidate     v1.0
  40.     libArray        v1.1
  41.     webform         v1.0
  42.    
  43.     */
  44.    
  45.     var $label;                 // String - HTML or Plain Text - The label for the input field.
  46.     var $field;                 // String - HTML - The input field w/ sprintf() style placeholders.
  47.     var $order;                 // Int - The order in the form layout for this field.
  48.     var $maxlength = 100;       // Int - The maximum number of chars in the field
  49.     var $size = 50;             // Int - The length of the box
  50.     var $readonly = false;      // Bool - Is this field read-only or not?
  51.     var $disabled = false;      // Bool - Is this field disabled or not?
  52.    
  53.     var $m_data;                // Array - Data for select, checkboxset, or radioset types. Used to build options and mark the appropriate option as selected/checked
  54.     var $m_type;                // String - This will hold the type: text, password, checkbox, radio, file, hidden, button, submit, select or textarea
  55.     var $m_form;                // Object Reference - to the form that this is a part of
  56.     var $m_field_name;          // String - the name of the field referenced in m_bound_field
  57.     var $m_bound_field;         // String Reference - to the property in $this->m_form->m_bound_model that this input field is bound to.
  58.     var $m_comparator;          // Object - Comparator.class.php - Used when iterating the $m_data array to build <select>, checkboxset()'s, and radioset()'s in comparison w/ val in the data_model
  59.    
  60.     function input_field($field_name, &$webform)
  61.     {
  62.         // This constructor will bind $this to the $webform object, then bind to the specific field (denoted by $field_name) in the $m_bound_model property of $webform
  63.         // @$field_name - The name of the field used in the HTML. Must be Plaintext. Must match the property name in the data_model class (and thusly the db column name)
  64.         // @$webform    - A reference to the webform object this is attached to. Validated as subclass of webform. Must be bound to a data_model class
  65.         // @return      - Void - Fatal Error raised if $this cannot bind to $webform
  66.    
  67.        
  68.         // First handle the $field_name. Validate as plaintext.
  69.         // In most cases, passing meta-chars would just cause us to throw a Warning while automatically stripping out the junk.
  70.         // But in the case of the $field_name, this is used in m_bind_field() w/ some variable-variable goodness to link to the corresponding property in the data model.
  71.         // Therefore, it's no good. A fatal will be thrown.
  72.         if ($field_name != htmlentities($field_name))
  73.         {
  74.             $e = new fatal_error('field_name passed to input_field() contains invalid chars. Only HTML-Safe chars will be used. ');
  75.             $e->comment = "[Requested field_name: {$field_name}]";
  76.             $e->class = 'webform';
  77.             $e->commit();
  78.         }
  79.        
  80.         $this->m_field_name = htmlentities($field_name);
  81.        
  82.         // Now validate & bind the webform
  83.         // A fatal-error will be raised if this cannot be completed    
  84.         if ($this->m_bind_form($webform))
  85.         {
  86.             // Now that we've bound to a webform, and we have a fieldname, we can bind to a specific field in the data_model class.
  87.             // (The Webform is bound to a data_model via the $webform->m_model property
  88.             // A fatal-error will be raised if this cannot be completed
  89.             $this->m_bind_field();
  90.            
  91.             // Now create a default comparator to be used
  92.             $this->set_comparator(new comparator(S_EQUAL));
  93.         }
  94.     }
  95.        
  96.     function set_label($label, $over_write = false)
  97.     {
  98.         // This function will add and auto-format the field's label w/ proper <label> tags.
  99.         // If $this->label already has text, and $over_write is not true, the function will fail, a warning will be raised, and false will be returned.
  100.         // Returns Boolean, False on error
  101.  
  102.         if (empty($this->label) || $over_write)
  103.         {  
  104.             $label = htmlentities($label);
  105.             $this->label = "<label class='webform_label' for='{$this->m_field_name}'>{$label}</label>";
  106.            
  107.             return true;
  108.         }
  109.        
  110.         $e = new error('set_label() failed. $this->label is not empty and the over_write flag was not set');
  111.         $e->comment = "[Requested label: {$label}] [Existing Label: {$this->label}]";
  112.         $e->class = 'webform';
  113.         $e->fatal = false;
  114.         $e->raise = false;
  115.         $e->log = true;
  116.         $e->commit();
  117.        
  118.         return false;
  119.     }
  120.  
  121.     function set_field($html, $over_write = false)
  122.     {
  123.         // This method is used to manually set the field by passing in the HTML w/ whatever webform tags you wish to implement. Seems like %value, at least, would be necessary.
  124.         // Returns Boolean
  125.        
  126.         /*
  127.             Note: if you're passing in a <select> it's important to know that if you want to have the webform automatically handle the selected element, you need to include
  128.             an %options tag and an $m_data array to build the <option>'s. Otherwise, when the user posts the form, if the form is re-rendered (due to a validation error) it
  129.             will NOT pre-select the users selected element.  The other option is for you to instantiate a NEW webform object on such a re-render and tie it to the same data_model
  130.             the the original form was tied to (literally the same instance, not just the same class) and then render THAT form,  instead of re-rendering the webform that was posted.
  131.            
  132.             Example:
  133.            
  134.             if ($_POST)
  135.             {
  136.                 $old = webform::load_from_post();
  137.                 $new = new myWebform($old->m_model);
  138.                 $new->render();
  139.             }
  140.  
  141.             FURTHER NOTE:
  142.             For these same reasons, it's reccommended that if you'd like to create a set of checkboxes or radio controls, that you let them be auto-created
  143.             using the set_field_as_checkboxset() or set_field_as_radioset(). Creating such controls on your own may yeild strange results if you try to re-render
  144.             the same form after a post.
  145.          */
  146.        
  147.         if (empty($this->field) || $over_write)
  148.         {
  149.             $this->field = $html;
  150.         }
  151.        
  152.         $e = new error('set_field() failed. $this->field is not empty and the over_write flag was not set');
  153.         $e->comment = "[Requested Field: {$html}] [Existing Field: {$this->field}]";
  154.         $e->class = 'webform';
  155.         $e->fatal = false;
  156.         $e->raise = false;
  157.         $e->log = true;
  158.         $e->commit();
  159.                
  160.         return false;
  161.     }
  162.    
  163.     function set_comparator($comparator)
  164.     {
  165.         // This method accepts a comparator object and sets it to the $this->m_comparator property.
  166.         // This is used when building the options for select, checkboxset, and radioset. As m_data is looped, a comparison is made to the curr value of the $m_bound_field so we
  167.         // know which item to mark as SELECTED (or CHECKED as the case may be). By using a comparator it lets you do more advanced comparisons than simple equality.
  168.         // For example: you may have a plant drop down box. In your data_model, though, that may (ie SHOULD) be a plant OBJECT. A simple comparison would fail. Instead you can create
  169.         // a comparator that then compares the plantID from the drop down box to the plant->plantID field in the data_model. You can do translations, string manipulation (like trim()
  170.         // or strtolower() or whatever), data type conversions, etc.
  171.        
  172.         // By default a S_EQUALITY type comparator is set.
  173.         // Returns Bool, throws fatal error if improper args are passed.
  174.        
  175.         if (is_a($comparator, 'comparator'))
  176.         {
  177.             $this->m_comparator = $comparator;
  178.             return true;
  179.         }
  180.        
  181.         $e = new fatal_error('An error has occured while processing this form.');
  182.         $e->comment = "set_comparator() Failed. A valid comparator object is expeceted.";
  183.         $e->class = 'webform';
  184.         $e->commit();
  185.        
  186.         return false;
  187.     }
  188.    
  189.     function render_field()
  190.     {
  191.         // This function will parse the field placeholders and return (hopefully) valid HTML
  192.         // We don't actually parse $this->field because we want to be able to parse-in a future value if/when the form is rendered again after the post.
  193.         // Returns HTML
  194.        
  195.         return $this->m_parse_field();
  196.     }
  197.    
  198.     function render_label()
  199.     {
  200.         // This function will parse the field placeholders and return (hopefully) valid HTML
  201.         // We don't actually parse $this->field because we want to be able to parse-in a future value if/when the form is rendered again after the post.
  202.         // Returns HTML
  203.        
  204.         return $this->m_parse_label();
  205.     }
  206.    
  207.     //********************************************************************************************************************************************************************************
  208.     // Input auto-builders
  209.     //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  210.    
  211.     function set_field_as_input($over_write = false)
  212.     {
  213.         // This function will add and auto-format the HTML for an <input> field.
  214.         // If $this->field already has content, and $over_write is not true, the function will fail, an error will be raised, and false will be returned
  215.        
  216.         if (empty($this->field) || $over_write)
  217.         {
  218.             $this->field = "<input type='text' id='%name' name='%name' value='%value' tabindex='%order' maxlength='%maxlength' size='%size' %readonly %disabled>";
  219.             return true;
  220.         }
  221.        
  222.         $e = new fatal_error('An error has occured while processing this form');
  223.         $e->comment = "set_field_as_input() failed. HTML already exists and the over_write flag is not set. [Existing HTML: {$this->field}]";
  224.         $e->class = 'webform';
  225.         $e->commit();
  226.        
  227.         return false;
  228.     }
  229.  
  230.     function set_field_as_textarea($over_write = false)
  231.     {
  232.         // This function will add and auto-format the HTML for an <textarea> field.
  233.         // If $this->field already has content, and $over_write is not true, the function will fail, an error will be raised, and false will be returned
  234.  
  235.         if (empty($this->field) || $over_write)
  236.         {
  237.             $this->field = "<textarea id='%name' name='%name' tabindex='%order' cols='%size' rows='%textarea_rows' %readonly %disabled>%value</textarea>";
  238.             return true;
  239.         }
  240.        
  241.         $e = new fatal_error('An error has occured while processing this form');
  242.         $e->comment = "set_field_as_textarea() failed. HTML already exists and the over_write flag is not set. [Existing HTML: {$this->field}]";
  243.         $e->class = 'webform';
  244.         $e->commit();
  245.        
  246.         return false;
  247.     }
  248.    
  249.     function set_field_as_password($over_write = false)
  250.     {
  251.         // This function will add and auto-format the HTML for an <input type='password'> field.
  252.         // If $this->field already has content, and $over_write is not true, the function will fail, an error will be raised, and false will be returned
  253.  
  254.         if (empty($this->field) || $over_write)
  255.         {
  256.             $this->field = "<input type='password' id='%name' name='%name' value='%value' tabindex='%order' size='%size' maxlength='%maxlength' %readonly %disabled>";
  257.             return true;
  258.         }
  259.        
  260.         $e = new fatal_error('An error has occured while processing this form');
  261.         $e->comment = "set_field_as_password() failed. HTML already exists and the over_write flag is not set. [Existing HTML: {$this->field}]";
  262.         $e->class = 'webform';
  263.         $e->commit();
  264.        
  265.         return false;
  266.     }
  267.    
  268.     function set_field_as_checkbox($over_write = false)
  269.     {
  270.         // This function will add and auto-format the HTML for an <input type='checkbox'> field.
  271.         // If $this->field already has content, and $over_write is not true, the function will fail, an error will be raised, and false will be returned
  272.        
  273.         if (empty($this->field) || $over_write)
  274.         {
  275.             $status = ((bool)$this->m_bound_field) ? ' checked ' : '';
  276.             $this->field = "<input type='checkbox' id='%name' name='%name' value='true' tabindex='%order' %value %readonly %disabled>";
  277.             return true;
  278.         }
  279.        
  280.         $e = new fatal_error('An error has occured while processing this form');
  281.         $e->comment = "set_field_as_checkbox() failed. HTML already exists and the over_write flag is not set. [Existing HTML: {$this->field}]";
  282.         $e->class = 'webform';
  283.         $e->commit();
  284.        
  285.         return false;          
  286.     }  
  287.  
  288.     // ** Buttons ** //
  289.                
  290.     function set_field_as_button($over_write = false)
  291.     {
  292.         // This function will add and auto-format the HTML for an <input type='button'> field.
  293.         // If $this->field already has content, and $over_write is not true, the function will fail, an error will be raised, and false will be returned
  294.        
  295.         if (empty($this->field) || $over_write)
  296.         {
  297.             $this->field = "<input type='button' id='%name' name='%name' value='%value' tabindex='%order' %disabled>";
  298.             return true;
  299.         }
  300.        
  301.         $e = new fatal_error('An error has occured while processing this form');
  302.         $e->comment = "set_field_as_button() failed. HTML already exists and the over_write flag is not set. [Existing HTML: {$this->field}]";
  303.         $e->class = 'webform';
  304.         $e->commit();
  305.        
  306.         return false;          
  307.     }
  308.  
  309.     function set_field_as_submit($over_write = false)
  310.     {
  311.         // This function will add and auto-format the HTML for an <input type='submit'> field.
  312.         // If $this->field already has content, and $over_write is not true, the function will fail, an error will be raised, and false will be returned
  313.        
  314.         if (empty($this->field) || $over_write)
  315.         {
  316.             $this->field = "<input type='submit' id='%name' name='%name' value='Submit' tabindex='%order' %disabled>";
  317.             return true;
  318.         }
  319.        
  320.         $e = new fatal_error('An error has occured while processing this form');
  321.         $e->comment = "set_field_as_submit() failed. HTML already exists and the over_write flag is not set. [Existing HTML: {$this->field}]";
  322.         $e->class = 'webform';
  323.         $e->commit();
  324.        
  325.         return false;
  326.     }  
  327.    
  328.     // ** Data-Bound Fields ** //
  329.    
  330.     function set_field_as_select($data, $over_write = false)
  331.     {
  332.         // This function will add and auto-format the HTML for an <select> field.
  333.         // If $this->field already has content, and $over_write is not true, the function will fail, an error will be raised, and false will be returned
  334.  
  335.         if (empty($this->field) || $over_write)
  336.         {
  337.             if (is_array($data))
  338.             {
  339.                 $this->m_data = $data;
  340.                
  341.                 // Now add the wrapping <select>
  342.                 $this->field = '<select id="%name" name="%name" tabindex="%order" %disabled>%options</select>';
  343.                
  344.                 return true;
  345.             }
  346.            
  347.             $e = new fatal_error('An error has occured while processing this form');
  348.             $e->comment = "set_field_as_select() failed. The data parameter expects an array. [Data: {$data}]";
  349.             $e->class = 'webform';
  350.             $e->commit();          
  351.         }
  352.        
  353.         $e = new fatal_error('An error has occured while processing this form');
  354.         $e->comment = "set_field_as_select() failed. HTML already exists and the over_write flag is not set. [Existing HTML: {$this->field}]";
  355.         $e->class = 'webform';
  356.         $e->commit();
  357.        
  358.         return false;
  359.     }
  360.    
  361.     function set_field_as_select_m($data, $over_write = false)
  362.     {
  363.         // This function will add and auto-format the HTML for an <select MULTIPLE> field.
  364.         // If $this->field already has content, and $over_write is not true, the function will fail, an error will be raised, and false will be returned
  365.  
  366.         if (empty($this->field) || $over_write)
  367.         {
  368.             if (is_array($data))
  369.             {
  370.                 $this->m_data = $data;
  371.                
  372.                 // Now add the wrapping <select>
  373.                 $this->field = '<select multiple id="%name" name="%name[]" tabindex="%order" %disabled>%options</select>';
  374.                
  375.                 return true;
  376.             }
  377.            
  378.             $e = new fatal_error('An error has occured while processing this form');
  379.             $e->comment = "set_field_as_select_m() failed. The data parameter expects an array. [Data: {$data}]";
  380.             $e->class = 'webform';
  381.             $e->commit();          
  382.         }
  383.        
  384.         $e = new fatal_error('An error has occured while processing this form');
  385.         $e->comment = "set_field_as_select_m() failed. HTML already exists and the over_write flag is not set. [Existing HTML: {$this->field}]";
  386.         $e->class = 'webform';
  387.         $e->commit();
  388.        
  389.         return false;
  390.     }  
  391.                
  392.     function set_field_as_checkboxset($data, $over_write = false)
  393.     {
  394.         // This function will add and auto-format the HTML for a set of <input type='checkbox'> fields.
  395.         // If $this->field already has content, and $over_write is not true, the function will fail, an error will be raised, and false will be returned
  396.  
  397.         if (empty($this->field) || $over_write)
  398.         {
  399.             if (is_array($data))
  400.             {
  401.                 $this->m_type = 'checkbox';
  402.                 $this->m_data = $data;
  403.                 return true;
  404.             }
  405.            
  406.             $e = new fatal_error('An error has occured while processing this form');
  407.             $e->comment = "set_field_as_checkboxset() failed. The data parameter expects an array. [Data: {$data}]";
  408.             $e->class = 'webform';
  409.             $e->commit();              
  410.         }
  411.        
  412.         $e = new fatal_error('An error has occured while processing this form');
  413.         $e->comment = "set_field_as_select() failed. HTML already exists and the over_write flag is not set. [Existing HTML: {$this->field}]";
  414.         $e->class = 'webform';
  415.         $e->commit();
  416.        
  417.         return false;      
  418.     }
  419.    
  420.     function set_field_as_radioset($data, $over_write = false)
  421.     {
  422.         // This function will add and auto-format the HTML for a set of <input type='radio'> fields.
  423.         // If $this->field already has content, and $over_write is not true, the function will fail, an error will be raised, and false will be returned
  424.  
  425.         if (empty($this->field) || $over_write)
  426.         {
  427.             if (is_array($data))
  428.             {
  429.                 $this->m_type = 'radio';
  430.                 $this->m_data = $data;
  431.                 return true;
  432.             }
  433.            
  434.             $e = new fatal_error('An error has occured while processing this form');
  435.             $e->comment = "set_field_as_radioset() failed. The data parameter expects an array. [Data: {$data}]";
  436.             $e->class = 'webform';
  437.             $e->commit();
  438.         }
  439.        
  440.         $e = new fatal_error('An error has occured while processing this form');
  441.         $e->comment = "set_field_as_select() failed. HTML already exists and the over_write flag is not set. [Existing HTML: {$this->field}]";
  442.         $e->class = 'webform';
  443.         $e->commit();
  444.        
  445.         return false;  
  446.     }
  447.    
  448.     // ** Special Fields ** //
  449.    
  450.     function set_field_as_select_plant($all_plants_option = false, $over_write = false)
  451.     {
  452.         // This function will add and auto-format the HTML for an <select> field.
  453.         // If $this->field already has content, and $over_write is not true, the function will fail, an error will be raised, and false will be returned
  454.  
  455.         if (empty($this->field) || $over_write)
  456.         {
  457.             $this->m_data = array();
  458.            
  459.             if ($all_plants_option)
  460.             {
  461.                 $this->m_data[0] = 'ALL Plants';
  462.             }
  463.            
  464.             $plants = plantCollection::load_all();
  465.             foreach($plants->items as $plant)
  466.             {
  467.                 $this->m_data[$plant->plantID] = $plant->shortname;
  468.             }
  469.             unset($plants);
  470.            
  471.  
  472.             // Now add the wrapping <select>
  473.             $this->field = '<select id="%name" name="%name" tabindex="%order" %disabled>%options</select>';
  474.            
  475.             return true;
  476.        
  477.         }
  478.        
  479.         $e = new fatal_error('An error has occured while processing this form');
  480.         $e->comment = "set_field_as_select_plant() failed. HTML already exists and the over_write flag is not set. [Existing HTML: {$this->field}]";
  481.         $e->class = 'webform';
  482.         $e->commit();
  483.        
  484.         return false;
  485.     }  
  486.    
  487.     // ** Miscellaneous Fields ** //
  488.    
  489.     function set_field_as_upload($over_write = false)
  490.     {
  491.         // This function will add and auto-format the HTML for an <input type='file'> field.
  492.         // If $this->field already has content, and $over_write is not true, the function will fail, an error will be raised, and false will be returned
  493.        
  494.         if (empty($this->field) || $over_write)
  495.         {
  496.             $this->field = "<input type='file' id='%name' name='%name' tabindex='%order' %disabled>";
  497.             return true;
  498.         }
  499.        
  500.         $e = new fatal_error('An error has occured while processing this form');
  501.         $e->comment = "set_field_as_upload() failed. HTML already exists and the over_write flag is not set. [Existing HTML: {$this->field}]";
  502.         $e->class = 'webform';
  503.         $e->commit();
  504.        
  505.         return false;          
  506.     }  
  507.    
  508.     function set_field_as_hidden($over_write = false)
  509.     {
  510.         // This function will add and auto-format the HTML for an <input type='hidden'> field.
  511.         // If $this->field already has content, and $over_write is not true, the function will fail, an error will be raised, and false will be returned
  512.        
  513.         if (empty($this->field) || $over_write)
  514.         {
  515.             $this->field = "<input type='hidden' id='%name' name='%name' value='%value'>";
  516.             return true;
  517.         }
  518.        
  519.         $e = new fatal_error('An error has occured while processing this form');
  520.         $e->comment = "set_field_as_hidden() failed. HTML already exists and the over_write flag is not set. [Existing HTML: {$this->field}]";
  521.         $e->class = 'webform';
  522.         $e->commit();
  523.        
  524.         return false;          
  525.     }
  526.                
  527.        
  528.     //********************************************************************************************************************************************************************************
  529.     // Private Methods
  530.     //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------     
  531.     function m_detect_type()
  532.     {
  533.         // This method is used to determine what kind of element is being used by munging the $this->field var
  534.         // Populates $this->m_type and returns void
  535.        
  536.         // Define and INSTR comparator that will look for the
  537.         // second argument inside the first, case insensitive.
  538.         $o = new comparator(S_INSTR);
  539.        
  540.         switch(true)
  541.         {
  542.             case ($o->evaluate($this->field, "type='text'")):
  543.             case ($o->evaluate($this->field, 'type="text"')):
  544.                
  545.                 $this->m_type = 'text';
  546.                 break;
  547.                
  548.             case ($o->evaluate($this->field, "type='password'")):
  549.             case ($o->evaluate($this->field, 'type="password"')):
  550.                
  551.                 $this->m_type = 'password';
  552.                 break;
  553.  
  554.             case ($o->evaluate($this->field, "type='checkbox'")):
  555.             case ($o->evaluate($this->field, 'type="checkbox"')):
  556.                
  557.                 $this->m_type = 'checkbox';
  558.                 break;
  559.                
  560.             case ($o->evaluate($this->field, "type='radio'")):
  561.             case ($o->evaluate($this->field, 'type="radio"')):
  562.                
  563.                 $this->m_type = 'radio';
  564.                 break;
  565.  
  566.             case ($o->evaluate($this->field, "type='file'")):
  567.             case ($o->evaluate($this->field, 'type="file"')):
  568.                
  569.                 $this->m_type = 'file';
  570.                 break;
  571.  
  572.             case ($o->evaluate($this->field, "type='hidden'")):
  573.             case ($o->evaluate($this->field, 'type="hidden"')):
  574.                
  575.                 $this->m_type = 'hidden';
  576.                 break;
  577.                
  578.             case ($o->evaluate($this->field, "type='button'")):
  579.             case ($o->evaluate($this->field, 'type="button"')):
  580.                
  581.                 $this->m_type = 'button';
  582.                 break;
  583.  
  584.             case ($o->evaluate($this->field, "type='submit'")):
  585.             case ($o->evaluate($this->field, 'type="submit"')):
  586.                
  587.                 $this->m_type = 'submit';
  588.                 break;
  589.                
  590.             case ($o->evaluate($this->field, '<select')):
  591.  
  592.                 $this->m_type = 'select';
  593.                 break;
  594.                
  595.             case ($o->evaluate($this->field, '<textarea')):
  596.                
  597.                 $this->m_type = 'textarea';
  598.                 break;
  599.                
  600.         }
  601.     }
  602.    
  603.     function m_build_options()
  604.     {
  605.         // This method is used to parse the $m_data array into <option> tags for selects.
  606.         // We have to re-build the <option> tags on ever render so we can mark the correct one as selected.
  607.         // Returns HTML <option> tags
  608.        
  609.         $options = '';
  610.        
  611.         if ('select' == $this->m_type && is_array($this->m_data))
  612.         {
  613.            
  614.             // If this has associative keys, use the array key as the HTML value and the array value as the Label.
  615.             // Otherwise, use the array value as both the HTML value and HTML label
  616.             if (libArray::is_associative_keys($this->m_data))
  617.             {              
  618.                 foreach ($this->m_data as $value => $label)
  619.                 {                  
  620.                     // Determine if this is the selected value before running it thru plain()
  621.                     // If multiple selections are allowed, the result will be an array in the $_POST, thus the in_array()
  622.                     $status = ($this->m_comparator->evaluate($this->m_bound_field, $value) || @in_array($value, $this->m_bound_field)) ? ' selected' : '';
  623.                            
  624.                     $value = htmlentities($value);
  625.                     $label = htmlentities($label);
  626.                    
  627.                     $options .= "<option value='{$value}'{$status}>{$label}</option>";
  628.                 }
  629.             }
  630.             else
  631.             {
  632.                 // The $data array is single dim.
  633.                 // This means that the <select> options will use the same key as display name
  634.                
  635.                 foreach ($this->m_data as $value)
  636.                 {
  637.                     // Determine if this is the selected value before running it thru html_safe()
  638.                     $status = ($value == $this->m_bound_field) ? ' selected' : '';
  639.                                                
  640.                     $value = @htmlentities($value);
  641.                    
  642.                     $options .= "<option{$status} value='{$value}'>{$value}</option>";
  643.                 }
  644.             }
  645.         }
  646.        
  647.         return $options;
  648.     }
  649.    
  650.     function m_build_checkboxset()
  651.     {
  652.         // This method is used to parse the $m_data array into <input type='checkbox'> tags for a checkboxset.
  653.         // We have to re-build the checkboxset on ever render so we can mark the correct one(s) as selected.
  654.         // Returns HTML tags
  655.                
  656.         $checkboxset = '';
  657.        
  658.         if ('checkbox' == $this->m_type && is_array($this->m_data))
  659.         {
  660.             if (libArray::is_associative_keys($this->m_data))
  661.             {
  662.                 // The $data array is an array of arrays.
  663.                 // This means each checkbox  has a corresponding text label in the [1] position of the nested-arrays
  664.                
  665.                 foreach ($this->m_data as $value => $label)
  666.                 {                  
  667.                     // Determine if this is the selected value before running it thru html_safe()
  668.                     // If more than one box is checked in the checkboxset, it'll be an array in the $_POST
  669.                     $status = ($this->m_comparator->evaluate($this->m_bound_field, $value) || @in_array($value, $this->m_bound_field)) ? ' checked' : '';
  670.                                            
  671.                     $value = @htmlentities($value);
  672.                     $label = @htmlentities($label);
  673.                    
  674.                     // We put the label after the checkbox so they will all be left-aligned
  675.                     $checkboxset .= "<br><input type='checkbox' name='%name[]' id='%name_{$value}' value='{$value}'{$status} %disabled><label for='%name_{$value}'>{$label}</label>";
  676.                 }
  677.             }
  678.             else
  679.             {
  680.                 // The $data array is single dim.
  681.                 // This means that the checkboxeswill use the same key as display name
  682.                
  683.                 foreach ($this->m_data as $value)
  684.                 {                              
  685.                     // Determine if this is the selected value before running it thru html_safe()
  686.                     $status = ($value == $this->m_bound_field) ? ' checked' : '';
  687.                                            
  688.                     $value = @htmlentities($value);
  689.                    
  690.                     $checkboxset .= "<br><input type='checkbox' name='%name[]' id='%name_{$value}' value='{$value}'{$status} %disabled><label for='%name_{$value}'>{$value}</label>";
  691.                 }      
  692.             }
  693.         }
  694.        
  695.         return $checkboxset;
  696.     }
  697.    
  698.     function m_build_radioset()
  699.     {
  700.         // This method is used to parse the $m_data array into <input type='radio'> tags for a radioset.
  701.         // We have to re-build the checkboxset on ever render so we can mark the correct one(s) as selected.
  702.         // Returns HTML tags
  703.                
  704.         $radioset = '';
  705.        
  706.         if ('radio' == $this->m_type && is_array($this->m_data))
  707.         {
  708.             if (libArray::is_associative_keys($this->m_data))
  709.             {
  710.                 // The $data array is an array of arrays.
  711.                 // This means each radio option has a corresponding text label in the [1] position of the nested-arrays
  712.                
  713.                 foreach ($this->m_data as $value => $label)
  714.                 {
  715.                     // Determine if this is the selected value before running it thru html_safe()
  716.                     $status = ($this->m_comparator->evaluate($this->m_bound_field, $value)) ? ' checked ' : '';                    
  717.                    
  718.                     // Clense them...
  719.                     $value = @htmlentities($value);
  720.                     $label = @htmlentities($label);
  721.                    
  722.                     // We put the label after the textbox so the textboxes will all be left-aligned
  723.                     $radioset .= "<br><input type='radio' name='%name' id='%name_{$value}' value='{$value}' {$status} %disabled><label for='%name_{$value}'>{$label}</label>";
  724.                 }
  725.             }
  726.             else
  727.             {
  728.                 // The $data array is single dim.
  729.                 // This means that the <select> options will use the same key as display name
  730.                
  731.                 foreach ($this->m_data as $value)
  732.                 {
  733.                     // Determine if this is the selected value before running it thru htmlentities()
  734.                     $status = ($value == $this->m_bound_field) ? ' checked ' : '';
  735.                                                
  736.                     $value = @htmlentities($value);
  737.                    
  738.                     $radioset .= "<br><input type='radio' id='%name_{$value}' name='%name' value='{$value}' {$status} %disabled>";
  739.                 }                      
  740.             }
  741.         }
  742.  
  743.         return $radioset;
  744.     }
  745.  
  746.     function m_parse_label()
  747.     {
  748.         // This private function will parse the place-holder values in $this->field
  749.         // Valid placeholders: %name
  750.         // Returns Void
  751.        
  752.         $label = $this->label;
  753.         $label = str_replace('%name', $this->m_field_name, $label);
  754.        
  755.         return $label;
  756.     }  
  757.  
  758.     function m_parse_field()
  759.     {
  760.         // This private function will parse the place-holder values in $this->field
  761.         // Valid placeholders: %name, %order, %value, %maxlength, %size, %readonly, %disabled, %textarea_rows, %options
  762.         // Returns Void
  763.        
  764.         // Always act on a local copy. The contents of $this->field are NEVER parsed. It retains the webform tags so we can
  765.         // re-parse new values into it if the form is posted and re-rendered (for example, to display validation errs and give user a chance to fix them)
  766.         $field = $this->field;
  767.        
  768.         // First, determine what kind of field this is.
  769.         // It doesn't matter here at this step, but we'll need to know for after the form gets posted and now is the best time to run the check
  770.         $this->m_detect_type();
  771.        
  772.         // Next, parse the %value.
  773.         // This is going to be different depending on the field type.
  774.         switch ($this->m_type)
  775.         {
  776.             case 'text':
  777.             case 'password':
  778.             case 'hidden':
  779.             case 'textarea':
  780.             case 'file':
  781.             case 'button':
  782.             case 'submit':
  783.                 $field = str_replace('%value', $this->m_bound_field, $field);
  784.                 break;
  785.                
  786.             case 'checkbox':   
  787.                 if (is_array($this->m_data))
  788.                 {
  789.                     // Checkbox Set. Must be rebuilt from $m_data
  790.                     $field = $this->m_build_checkboxset();
  791.                 }
  792.                 else
  793.                 {
  794.                     // Single Checkbox.
  795.                     $field = ((bool)$this->m_bound_field) ? str_replace('%value', ' checked ', $field) : str_replace('%value', '', $field);
  796.                 }
  797.                 break;
  798.                
  799.             case 'radio':
  800.                 if (is_array($this->m_data))
  801.                 {
  802.                     // Checkbox Set. Must be rebuilt from $m_data
  803.                     $field = $this->m_build_radioset();
  804.                 }
  805.                 else
  806.                 {
  807.                     // Single Checkbox.
  808.                     $field = ((bool)$this->m_bound_field) ? str_replace('%value', ' checked ', $field) : str_replace('%value', '', $field);
  809.                 }              
  810.                 break;
  811.                
  812.             case 'select':
  813.                 // At present, %value is N/A when dealing w/ <select>
  814.                 break;
  815.         }      
  816.        
  817.        
  818.         $field = str_replace('%name',       $this->m_field_name,    $field);
  819.         $field = str_replace('%order',      $this->order,           $field);
  820.        
  821.         $field = str_replace('%maxlength',  $this->maxlength,       $field);
  822.         $field = str_replace('%size',       $this->size,            $field);
  823.        
  824.         $field = str_replace('%readonly',   ($this->readonly) ? 'readonly' : '', $field);
  825.         $field = str_replace('%disabled',   ($this->disabled) ? 'disabled' : '', $field);
  826.        
  827.         // This is used to figure out the rows of the textarea
  828.         // Simply taking the maxlength, dividing by $size (which is used in the cols attribute of a textarea) to determine needed rows
  829.         $field = str_replace('%textarea_rows',  ($this->maxlength / $this->size > 1) ? intval($this->maxlength / $this->size) : 1,  $field);
  830.        
  831.         // This is going to re-build the <options> on every call so we can keep the selected option current.
  832.         // See comments in set_field() for more info
  833.         //$field = str_replace('%options', $this->m_build_options(), $field);
  834.         $field = preg_replace('/%options/', $this->m_build_options(), $field );
  835.  
  836.         return $field;
  837.     }  
  838.    
  839.     function m_bind_form($webform)
  840.     {
  841.         // Expects a reference to a valid webform object.
  842.         // Throws fatal error if not supplied
  843.        
  844.         if (false == is_subclass_of($webform, 'webform'))
  845.         {
  846.             $e = new fatal_error('An error has occured while processing this form');
  847.             $e->comment = 'input_field object could not bind form. A valid webform object is expected.';
  848.             $e->class = 'webform';
  849.             $e->commit();
  850.            
  851.             return false;
  852.         }
  853.        
  854.         // It's all validated.
  855.         // Bind the form to m_form, and bind the appropriate field on the form's bound data_model.
  856.         $this->m_form = $webform;
  857.        
  858.         return true;
  859.     }  
  860.        
  861.     function m_bind_field()
  862.     {
  863.         // This method expects the object to already be bound to a webfrom and have a m_field_name set.
  864.         // It will connect to the data model via the webform and create a reference to the matching property.  
  865.         // Returns Boolean.
  866.        
  867.         if (false == is_subclass_of($this->m_form->m_model, 'data_model'))
  868.         {
  869.             $e = new fatal_error('An error has occured while processing this form');
  870.             $e->comment = 'input_field object could not bind form. The form object is valid, but it does not contain a valid data_model object';
  871.             $e->class = 'webform';
  872.             $e->commit();
  873.            
  874.             return false;
  875.         }      
  876.        
  877.         $this->m_bound_field =& $this->m_form->m_model->{$this->m_field_name};
  878.        
  879.         return true;
  880.     }
  881. }
  882.  
  883. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement