Source for file jFormsBase.class.php

Documentation is available at jFormsBase.class.php

  1. <?php
  2. /**
  3. @package     jelix
  4. @subpackage  forms
  5. @author      Laurent Jouanneau
  6. @contributor Dominique Papin
  7. @contributor Bastien Jaillot, Steven Jehannet
  8. @contributor Christophe Thiriot, Julien Issler, Olivier Demah
  9. @copyright   2006-2010 Laurent Jouanneau, 2007 Dominique Papin, 2008 Bastien Jaillot
  10. @copyright   2008-2009 Julien Issler, 2009 Olivier Demah, 2010 Steven Jehannet
  11. @link        http://www.jelix.org
  12. @licence     http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public Licence, see LICENCE file
  13. */
  14.  
  15. /**
  16.  *
  17.  */
  18. require(JELIX_LIB_PATH.'forms/jFormsControl.class.php');
  19. require(JELIX_LIB_PATH.'forms/jFormsDatasource.class.php');
  20. require_once(JELIX_LIB_UTILS_PATH.'jDatatype.class.php');
  21.  
  22. /**
  23.  * exception for jforms
  24.  * @package     jelix
  25.  * @subpackage  forms
  26.  */
  27. class jExceptionForms extends jException {
  28.  
  29. }
  30.  
  31. /**
  32.  * base class of all form classes generated by the jform compiler
  33.  * @package     jelix
  34.  * @subpackage  forms
  35.  */
  36. abstract class jFormsBase {
  37.  
  38.     const SECURITY_LOW = 0;
  39.     const SECURITY_CSRF = 1;
  40.  
  41.     public $securityLevel = 1;
  42.  
  43.     /**
  44.      * List of all form controls
  45.      * array of jFormsControl objects
  46.      * @var array 
  47.      * @see jFormsControl
  48.      */
  49.     protected $controls = array();
  50.  
  51.     /**
  52.      * List of top controls
  53.      * array of jFormsControl objects
  54.      * @var array 
  55.      * @see jFormsControl
  56.      */
  57.     protected $rootControls = array();
  58.  
  59.     /**
  60.      * List of submit buttons
  61.      * array of jFormsControl objects
  62.      * @var array 
  63.      * @see jFormsControl
  64.      */
  65.     protected $submits = array();
  66.  
  67.     /**
  68.      * Reset button
  69.      * @var jFormsControl 
  70.      * @see jFormsControl
  71.      * @since 1.0
  72.      */
  73.     protected $reset = null;
  74.  
  75.     /**
  76.      * List of uploads controls
  77.      * array of jFormsControl objects
  78.      * @var array 
  79.      * @see jFormsControl
  80.      */
  81.     protected $uploads = array();
  82.  
  83.     /**
  84.      * List of hidden controls
  85.      * array of jFormsControl objects
  86.      * @var array 
  87.      * @see jFormsControl
  88.      */
  89.     protected $hiddens = array();
  90.  
  91.     /**
  92.      * List of htmleditorcontrols
  93.      * array of jFormsControl objects
  94.      * @var array 
  95.      * @see jFormsControl
  96.      */
  97.     protected $htmleditors = array();
  98.  
  99.     /**
  100.      * List of wikieditorcontrols
  101.      * array of jFormsControl objects
  102.      * @var array 
  103.      * @see jFormsControl
  104.      * @since 1.2
  105.      */
  106.     protected $wikieditors = array();
  107.  
  108.     /**
  109.      * the data container
  110.      * @var jFormsDataContainer 
  111.      */
  112.     protected $container = null;
  113.  
  114.     /**
  115.      * content list of available form builder
  116.      * @var boolean 
  117.      */
  118.     protected $builders = array();
  119.  
  120.     /**
  121.      * the form selector
  122.      * @var string 
  123.      */
  124.     protected $sel;
  125.  
  126.     /**
  127.      * @param string $sel the form selector
  128.      * @param jFormsDataContainer $container the data container
  129.      * @param boolean $reset says if the data should be reset
  130.      */
  131.     public function __construct($sel$container$reset false){
  132.         $this->container = $container;
  133.         if($reset){
  134.             $this->container->clear();
  135.         }
  136.         $this->container->updatetime = time();
  137.         $this->sel = $sel;
  138.     }
  139.  
  140.     public function getSelector({
  141.         return $this->sel;
  142.     }
  143.  
  144.     /**
  145.      * set form data from request parameters
  146.      */
  147.     public function initFromRequest(){
  148.         $req jApp::coord()->request;
  149.         if ($this->securityLevel == jFormsBase::SECURITY_CSRF{
  150.             if ($this->container->token !== $req->getParam('__JFORMS_TOKEN__'))
  151.                 throw new jException("jelix~formserr.invalid.token");
  152.         }
  153.  
  154.         foreach($this->rootControls as $name=>$ctrl){
  155.             if(!$this->container->isActivated($name|| $this->container->isReadOnly($name))
  156.                 continue;
  157.             $ctrl->setValueFromRequest($req);
  158.         }
  159.     }
  160.  
  161.     /**
  162.      * check validity of all data form
  163.      * @return boolean true if all is ok
  164.      */
  165.     public function check(){
  166.         $this->container->errors = array();
  167.         foreach($this->rootControls as $name=>$ctrl){
  168.             if($this->container->isActivated($name))
  169.                 $ctrl->check();
  170.         }
  171.         return count($this->container->errors== 0;
  172.     }
  173.  
  174.     /**
  175.      * prepare an object with values of all controls
  176.      * @param object $object the object to fill
  177.      * @param array $properties array of 'propertyname'=>array('required'=>true/false,
  178.      *                           'defaultValue'=>$value, 'unifiedType'=>$datatype)
  179.      *    values of datatype = same as jdb unified types
  180.      */
  181.     public function prepareObjectFromControls($object$properties null){
  182.         if ($properties == null{
  183.             $properties get_object_vars($object);
  184.             foreach($properties as $n=>$v{
  185.                 if (!is_null($v)) {
  186.                     $r true;
  187.                     $t gettype($v);
  188.                 }
  189.                 else {
  190.                     $t 'varchar';
  191.                     $r false;
  192.                 }
  193.                 $properties[$n]=array('required'=>$r'defaultValue'=>$v'unifiedType'=>$t);
  194.             }
  195.         }
  196.  
  197.         foreach($this->controls as $name=>$ctrl){
  198.             if(!isset($properties[$name]))
  199.                 continue;
  200.  
  201.             if(is_array($this->container->data[$name])){
  202.                 if (count($this->container->data[$name]==1{
  203.                     $object->$name $this->container->data[$name][0];
  204.                 }
  205.                 else
  206.                     // do nothing for arrays ?
  207.                     continue;
  208.             }
  209.             else{
  210.                 $object->$name $this->container->data[$name];
  211.             }
  212.  
  213.             if($object->$name == '' && !$properties[$name]['required']{
  214.                 // if no value and if the property is not required, we set null to it
  215.                 $object->$name null;
  216.             }
  217.             else {
  218.                 if (isset($properties[$name]['unifiedType']))
  219.                     $type $properties[$name]['unifiedType'];
  220.                 else
  221.                     $type $properties[$name]['datatype']// for compatibility
  222.  
  223.                 if($object->$name == '' && $properties[$name]['defaultValue'!== null
  224.                         && in_array($type,
  225.                                     array('int','integer','double','float''numeric''decimal'))) {
  226.                     $object->$name $properties[$name]['defaultValue'];
  227.                 }
  228.                 else if$type == 'boolean' && !is_bool($object->$name)) {
  229.                     $object->$name (intval($object->$name== 1|| strtolower($object->$name=== 'true'
  230.                                       || $object->$name === 't' || $object->$name === 'on');
  231.                 }
  232.                 else if($ctrl->datatype instanceof jDatatypeLocaleDateTime
  233.                          && $type == 'datetime'{
  234.                     $dt new jDateTime();
  235.                     $dt->setFromString($object->$namejDateTime::LANG_DTFORMAT);
  236.                     $object->$name $dt->toString(jDateTime::DB_DTFORMAT);
  237.                 }
  238.                 elseif($ctrl->datatype instanceof jDatatypeLocaleDate
  239.                         && $type == 'date'{
  240.                     $dt new jDateTime();
  241.                     $dt->setFromString($object->$namejDateTime::LANG_DFORMAT);
  242.                     $object->$name $dt->toString(jDateTime::DB_DFORMAT);
  243.                 }
  244.             }
  245.         }
  246.     }
  247.  
  248.     /**
  249.      * set form data from a DAO
  250.      * @param string $daoSelector the selector of a dao file
  251.      * @param string $key the primary key for the dao. if null, takes the form ID as primary key
  252.      * @param string $dbProfile the jDb profile to use with the dao
  253.      * @see jDao
  254.      * @return jDaoRecordBase 
  255.      */
  256.     public function initFromDao($daoSelector$key null$dbProfile=''){
  257.         if($key === null)
  258.             $key $this->container->formId;
  259.         $dao jDao::create($daoSelector$dbProfile);
  260.         $daorec $dao->get($key);
  261.         if(!$daorec{
  262.             if(is_array($key))
  263.                 $key var_export($key,true);
  264.             throw new jExceptionForms('jelix~formserr.bad.formid.for.dao',
  265.                                       array($daoSelector$key$this->sel));
  266.         }
  267.  
  268.         $prop $dao->getProperties();
  269.         foreach($this->controls as $name=>$ctrl){
  270.             if(isset($prop[$name])) {
  271.                 $ctrl->setDataFromDao($daorec->$name$prop[$name]['datatype']);
  272.             }
  273.         }
  274.         return $daorec;
  275.     }
  276.  
  277.     /**
  278.      * prepare a dao with values of all controls
  279.      * @param string $daoSelector the selector of a dao file
  280.      * @param string $key the primary key for the dao. if null, takes the form ID as primary key
  281.      * @param string $dbProfile the jDb profile to use with the dao
  282.      * @return mixed return three vars : $daorec, $dao, $toInsert which have to be extracted
  283.      * @see jDao
  284.      */
  285.     public function prepareDaoFromControls($daoSelector$key null$dbProfile=''){
  286.         $dao jDao::get($daoSelector$dbProfile);
  287.  
  288.         if($key === null)
  289.             $key $this->container->formId;
  290.  
  291.         if($key != null && ($daorec $dao->get($key))) {
  292.             $toInsertfalse;
  293.         }else{
  294.             $daorec jDao::createRecord($daoSelector$dbProfile);
  295.             if($key != null)
  296.                 $daorec->setPk($key);
  297.             $toInserttrue;
  298.         }
  299.         $this->prepareObjectFromControls($daorec$dao->getProperties());
  300.         return compact("daorec""dao""toInsert");
  301.     }
  302.  
  303.     /**
  304.      * save data using a dao.
  305.      * it call insert or update depending the value of the formId stored in the container
  306.      * @param string $daoSelector the selector of a dao file
  307.      * @param string $key the primary key for the dao. if null, takes the form ID as primary key
  308.      * @param string $dbProfile the jDb profile to use with the dao
  309.      * @return mixed  the primary key of the new record in a case of inserting
  310.      * @see jDao
  311.      */
  312.     public function saveToDao($daoSelector$key null$dbProfile=''){
  313.         $results $this->prepareDaoFromControls($daoSelector,$key,$dbProfile);
  314.         extract($results)//use a temp variable to avoid notices
  315.         if($toInsert){
  316.             // todo : what about updating the formId with the Pk ?
  317.             $dao->insert($daorec);
  318.         }else{
  319.             $dao->update($daorec);
  320.         }
  321.         return $daorec->getPk();
  322.     }
  323.  
  324.     /**
  325.      * set data from a DAO, in a control
  326.      *
  327.      * The control must be a container like checkboxes or listbox with multiple attribute.
  328.      * The form should contain a formId
  329.      *
  330.      * The Dao should map to an "association table" : its primary key should be composed by
  331.      * the primary key stored in the formId (or the given primarykey) + the field which will contain one of
  332.      * the values of the control. If this order is not the same as defined into the dao,
  333.      * you should provide the list of property names which corresponds to the primary key
  334.      * in this order : properties for the formId, followed by the property which contains
  335.      * the value.
  336.      * @param string $name  the name of the control
  337.      * @param string $daoSelector the selector of a dao file
  338.      * @param mixed  $primaryKey the primary key if the form have no id. (optional)
  339.      * @param mixed  $primaryKeyNames list of field corresponding to primary keys (optional)
  340.      * @param string $dbProfile the jDb profile to use with the dao
  341.      * @see jDao
  342.      */
  343.     public function initControlFromDao($name$daoSelector$primaryKey null$primaryKeyNames=null$dbProfile=''){
  344.  
  345.         if (!isset($this->controls[$name]))
  346.             throw new jExceptionForms('jelix~formserr.unknown.control2'array($name$this->sel));
  347.  
  348.         if(!$this->controls[$name]->isContainer()){
  349.             throw new jExceptionForms('jelix~formserr.control.not.container'array($name$this->sel));
  350.         }
  351.  
  352.         if(!$this->container->formId)
  353.             throw new jExceptionForms('jelix~formserr.formid.undefined.for.dao'array($name$this->sel));
  354.  
  355.         if($primaryKey === null)
  356.             $primaryKey $this->container->formId;
  357.  
  358.         if(!is_array($primaryKey))
  359.             $primaryKey =array($primaryKey);
  360.  
  361.         $dao jDao::create($daoSelector$dbProfile);
  362.  
  363.         $conditions jDao::createConditions();
  364.         if($primaryKeyNames)
  365.             $pkNamelist $primaryKeyNames;
  366.         else
  367.             $pkNamelist $dao->getPrimaryKeyNames();
  368.  
  369.         foreach($primaryKey as $k=>$pk){
  370.             $conditions->addCondition ($pkNamelist[$k]'='$pk);
  371.         }
  372.  
  373.         $results $dao->findBy($conditions);
  374.         $valuefield $pkNamelist[$k+1];
  375.         $val array();
  376.         foreach($results as $res){
  377.             $val[]=$res->$valuefield;
  378.         }
  379.         $this->controls[$name]->setData($val);
  380.     }
  381.  
  382.  
  383.     /**
  384.      * save data of a control using a dao.
  385.      *
  386.      * The control must be a container like checkboxes or listbox with multiple attribute.
  387.      * If the form contain a new record (no formId), you should call saveToDao before
  388.      * in order to get a new id (the primary key of the new record), or you should get a new id
  389.      * by an other way. then you must pass this primary key in the third argument.
  390.      * If the form has already a formId, then it will be used as a primary key, unless
  391.      * you give one in the third argument.
  392.      *
  393.      * The Dao should map to an "association table" : its primary key should be
  394.      * the primary key stored in the formId + the field which will contain one of
  395.      * the values of the control. If this order is not the same as defined into the dao,
  396.      * you should provide the list of property names which corresponds to the primary key
  397.      * in this order : properties for the formId, followed by the property which contains
  398.      * the value.
  399.      * All existing records which have the formid in their keys are deleted
  400.      * before to insert new values.
  401.      *
  402.      * @param string $controlName  the name of the control
  403.      * @param string $daoSelector the selector of a dao file
  404.      * @param mixed  $primaryKey the primary key if the form have no id. (optional)
  405.      * @param mixed  $primaryKeyNames list of field corresponding to primary keys (optional)
  406.      * @param string $dbProfile the jDb profile to use with the dao
  407.      * @see jDao
  408.      */
  409.     public function saveControlToDao($controlName$daoSelector$primaryKey null$primaryKeyNames=null$dbProfile=''){
  410.  
  411.         if (!isset($this->controls[$controlName]))
  412.             throw new jExceptionForms('jelix~formserr.unknown.control2'array($controlName$this->sel));
  413.  
  414.         if(!$this->controls[$controlName]->isContainer()){
  415.             throw new jExceptionForms('jelix~formserr.control.not.container'array($controlName$this->sel));
  416.         }
  417.  
  418.         $values $this->container->data[$controlName];
  419.         if(!is_array($values&& $values != '')
  420.             throw new jExceptionForms('jelix~formserr.value.not.array'array($controlName$this->sel));
  421.  
  422.         if(!$this->container->formId && !$primaryKey)
  423.             throw new jExceptionForms('jelix~formserr.formid.undefined.for.dao'array($controlName$this->sel));
  424.  
  425.         if($primaryKey === null)
  426.             $primaryKey $this->container->formId;
  427.  
  428.         if(!is_array($primaryKey))
  429.             $primaryKey =array($primaryKey);
  430.  
  431.         $dao jDao::create($daoSelector$dbProfile);
  432.         $daorec jDao::createRecord($daoSelector$dbProfile);
  433.  
  434.         $conditions jDao::createConditions();
  435.         if($primaryKeyNames)
  436.             $pkNamelist $primaryKeyNames;
  437.         else
  438.             $pkNamelist $dao->getPrimaryKeyNames();
  439.  
  440.         foreach($primaryKey as $k=>$pk){
  441.             $conditions->addCondition ($pkNamelist[$k]'='$pk);
  442.             $daorec->{$pkNamelist[$k]$pk;
  443.         }
  444.  
  445.         $dao->deleteBy($conditions);
  446.         if (is_array($values)) {
  447.             $valuefield $pkNamelist[$k+1];
  448.             foreach($values as $value){
  449.                 $daorec->$valuefield $value;
  450.                 $dao->insert($daorec);
  451.             }
  452.         }
  453.     }
  454.  
  455.     /**
  456.      * return list of errors found during the check
  457.      * @return array 
  458.      * @see jFormsBase::check
  459.      */
  460.     public function getErrors(){  return $this->container->errors;  }
  461.  
  462.     /**
  463.      * set an error message on a specific field
  464.      * @param string $field the field name
  465.      * @param string $mesg  the error message string
  466.      */
  467.     public function setErrorOn($field$mesg){
  468.         $this->container->errors[$field]=$mesg;
  469.     }
  470.  
  471.     /**
  472.      *
  473.      * @param string $name the name of the control/data
  474.      * @param string $value the data value
  475.      */
  476.     public function setData($name$value{
  477.         if (!isset($this->controls[$name]))
  478.             throw new jExceptionForms('jelix~formserr.unknown.control2'array($name$this->sel));
  479.  
  480.         $this->controls[$name]->setData($value);
  481.     }
  482.  
  483.     /**
  484.      *
  485.      * @param string $name the name of the  control/data
  486.      * @return string the data value
  487.      */
  488.     public function getData($name{
  489.         if(isset($this->container->data[$name]))
  490.             return $this->container->data[$name];
  491.         else return null;
  492.     }
  493.  
  494.     /**
  495.      * @return array form data
  496.      */
  497.     public function getAllData()return $this->container->data}
  498.  
  499.     /**
  500.      * deactivate (or reactivate) a control
  501.      * When a control is deactivated, it is not displayes anymore in the output form
  502.      * @param string $name  the name of the control
  503.      * @param boolean $deactivation   TRUE to deactivate, or FALSE to reactivate
  504.      */
  505.     public function deactivate($name$deactivation=true{
  506.         if (!isset($this->controls[$name]))
  507.             throw new jExceptionForms('jelix~formserr.unknown.control2'array($name$this->sel));
  508.  
  509.         $this->controls[$name]->deactivate($deactivation);
  510.     }
  511.  
  512.     /**
  513.     * check if a control is activated
  514.     * @param string $name the control name
  515.     * @return boolean true if it is activated
  516.     */
  517.     public function isActivated($name{
  518.         return $this->container->isActivated($name);
  519.     }
  520.  
  521.  
  522.     /**
  523.      * set a control readonly or not
  524.      * @param boolean $r true if you want read only
  525.      */
  526.     public function setReadOnly($name$r true{
  527.         if (!isset($this->controls[$name]))
  528.             throw new jExceptionForms('jelix~formserr.unknown.control2'array($name$this->sel));
  529.  
  530.         $this->controls[$name]->setReadOnly($r);
  531.     }
  532.  
  533.     /**
  534.      * check if a control is readonly
  535.      * @return boolean true if it is readonly
  536.      */
  537.     public function isReadOnly($name{
  538.         return $this->container->isReadOnly($name);
  539.     }
  540.  
  541.     /**
  542.      * @return jFormsDataContainer 
  543.      */
  544.     public function getContainer()return $this->container}
  545.  
  546.  
  547.     /**
  548.      * @return array of jFormsControl objects
  549.      */
  550.     public function getRootControls()return $this->rootControls}
  551.  
  552.     /**
  553.      * @return array of jFormsControl objects
  554.      */
  555.     public function getControls()return $this->controls}
  556.  
  557.     /**
  558.      * @param string $name the control name you want to get
  559.      * @return jFormsControl 
  560.      * @since jelix 1.0
  561.      */
  562.     public function getControl($name{
  563.         if(isset($this->controls[$name]))
  564.             return $this->controls[$name];
  565.         else return null;
  566.     }
  567.  
  568.     /**
  569.      * @return array of jFormsControl objects
  570.      */
  571.     public function getSubmits()return $this->submits}
  572.  
  573.      /**
  574.      * @return array of jFormsControl objects
  575.      * @since 1.1
  576.      */
  577.     public function getHiddens()return $this->hiddens}
  578.  
  579.      /**
  580.      * @return array of jFormsControl objects
  581.      * @since 1.1
  582.      */
  583.     public function getHtmlEditors()return $this->htmleditors}
  584.  
  585.      /**
  586.      * @return array of jFormsControl objects
  587.      * @since 1.2
  588.      */
  589.     public function getWikiEditors()return $this->wikieditors}
  590.  
  591.     /**
  592.      * @return array of jFormsControl objects
  593.      * @since 1.2
  594.      */
  595.     public function getUploads()return $this->uploads}
  596.  
  597.     /**
  598.      * call this method after initilization of the form, in order to track
  599.      * modified controls
  600.      * @since 1.1
  601.      */
  602.     public function initModifiedControlsList(){
  603.         $this->container->originalData $this->container->data;
  604.     }
  605.  
  606.     /**
  607.      * returns the old values of the controls which have been modified since
  608.      * the call of the method initModifiedControlsList()
  609.      * @return array key=control id,  value=old value
  610.      * @since 1.1
  611.      */
  612.     public function getModifiedControls(){
  613.         if (count($this->container->originalData)) {
  614.  
  615.             // we musn't use array_diff_assoc because it convert array values
  616.             // to "Array" before comparison, so these values are always equal for it.
  617.             // We shouldn't use array_udiff_assoc  because it crashes PHP, at least on
  618.             // some PHP version.
  619.             // so we have to compare by ourself.
  620.  
  621.             $result array();
  622.             $orig $this->container->originalData;
  623.             foreach($this->container->data as $k=>$v1{
  624.  
  625.                 if (!array_key_exists($k$orig)) {
  626.                     continue;
  627.                 }
  628.  
  629.                 if($this->_diffValues($orig[$k]$v1))  {
  630.                     $result[$k$orig[$k];
  631.                     continue;
  632.                 }
  633.             }
  634.             return $result;
  635.         }
  636.         else
  637.             return $this->container->data;
  638.     }
  639.  
  640.     protected function _diffValues(&$v1&$v2{
  641.         if (is_array($v1&& is_array($v2)) {
  642.             $comp array_merge(array_diff($v1$v2),array_diff($v2$v1));
  643.             return !empty($comp);
  644.         }
  645.         elseif(empty($v1&& empty($v2)){
  646.             return false;
  647.         }
  648.         elseif (is_array($v1|| is_array($v2)) {
  649.             return true;
  650.         }
  651.         else {
  652.             return !($v1==$v2);
  653.             //return !($v2== (string)$v1);
  654.         }
  655.     }
  656.  
  657.     /**
  658.      * @return array of jFormsControl objects
  659.      */
  660.     public function getReset()return $this->reset}
  661.  
  662.     /**
  663.      * @return string the formId
  664.      */
  665.     public function id()return $this->container->formId}
  666.  
  667.     /**
  668.      * @return boolean 
  669.      */
  670.     public function hasUpload(return count($this->uploads)>0}
  671.  
  672.     /**
  673.      * @param string $buildertype  the type name of a form builder.
  674.      *           if the name begins by 'legacy.', it load a legacy builder plugin (jelix <=1.4)
  675.      * @return \jelix\forms\Builder\BuilderBase | jFormsBuilderBase
  676.      */
  677.     public function getBuilder($buildertype){
  678.  
  679.         $legacy false;
  680.         if ($buildertype == ''{
  681.             $buildertype $plugintype 'html';
  682.         }
  683.         else if (preg_match('/^legacy\.(.*)$/'$buildertype$m)) {
  684.             $legacy true;
  685.             $plugintype $m[1];
  686.         }
  687.         else {
  688.             $plugintype $buildertype;
  689.         }
  690.  
  691.         if(isset($this->builders[$buildertype]))
  692.             return $this->builders[$buildertype];
  693.  
  694.         if (!$legacy{
  695.             $o jApp::loadPlugin($plugintype'formbuilder''.formbuilder.php'$plugintype.'FormBuilder'$this);
  696.         }
  697.         else {
  698.             include_once(JELIX_LIB_PATH.'forms/legacy/jFormsBuilderBase.class.php');
  699.             $o jApp::loadPlugin($plugintype'jforms''.jformsbuilder.php'$plugintype.'JformsBuilder'$this);
  700.         }
  701.  
  702.         if ($o{
  703.             $this->builders[$buildertype$o;
  704.             return $o;
  705.         }else{
  706.             throw new jExceptionForms('jelix~formserr.invalid.form.builder'array($buildertype$this->sel));
  707.         }
  708.     }
  709.  
  710.     /**
  711.      * save an uploaded file in the given directory. the given control must be
  712.      * an upload control of course.
  713.      * @param string $controlName the name of the upload control
  714.      * @param string $path path of the directory where to store the file. If it is not given,
  715.      *                      it will be stored under the var/uploads/_modulename~formname_/ directory
  716.      * @param string $alternateName a new name for the file. If it is not given, the file
  717.      *                               while be stored with the original name
  718.      * @return boolean true if the file has been saved correctly
  719.      */
  720.     public function saveFile($controlName$path=''$alternateName=''{
  721.         if ($path == ''{
  722.             $path jApp::varPath('uploads/'.$this->sel.'/');
  723.         else if (substr($path-11!= '/'{
  724.             $path.='/';
  725.         }
  726.  
  727.         if(!isset($this->controls[$controlName]|| $this->controls[$controlName]->type != 'upload')
  728.             throw new jExceptionForms('jelix~formserr.invalid.upload.control.name'array($controlName$this->sel));
  729.  
  730.         if(!isset($_FILES[$controlName]|| $_FILES[$controlName]['error']!= UPLOAD_ERR_OK)
  731.             return false;
  732.  
  733.         if($this->controls[$controlName]->maxsize && $_FILES[$controlName]['size'$this->controls[$controlName]->maxsize){
  734.             return false;
  735.         }
  736.         jFile::createDir($path);
  737.         if ($alternateName == ''{
  738.             $path.= $_FILES[$controlName]['name'];
  739.         else {
  740.             $path.= $alternateName;
  741.         }
  742.         return move_uploaded_file($_FILES[$controlName]['tmp_name']$path);
  743.     }
  744.  
  745.     /**
  746.      * save all uploaded file in the given directory
  747.      * @param string $path path of the directory where to store the file. If it is not given,
  748.      *                      it will be stored under the var/uploads/_modulename~formname_/ directory
  749.      */
  750.     public function saveAllFiles($path=''{
  751.         if ($path == ''{
  752.             $path jApp::varPath('uploads/'.$this->sel.'/');
  753.         else if (substr($path-11!= '/'{
  754.             $path.='/';
  755.         }
  756.  
  757.         if(count($this->uploads))
  758.             jFile::createDir($path);
  759.  
  760.         foreach($this->uploads as $ref=>$ctrl){
  761.  
  762.             if(!isset($_FILES[$ref]|| $_FILES[$ref]['error']!= UPLOAD_ERR_OK)
  763.                 continue;
  764.             if($ctrl->maxsize && $_FILES[$ref]['size'$ctrl->maxsize)
  765.                 continue;
  766.  
  767.             move_uploaded_file($_FILES[$ref]['tmp_name']$path.$_FILES[$ref]['name']);
  768.         }
  769.     }
  770.  
  771.     /**
  772.     * add a control to the form
  773.     * @param jFormsControl $control the control to add
  774.     */
  775.     public function addControl($control){
  776.         $this->rootControls [$control->ref$control;
  777.         $this->addChildControl($control);
  778.  
  779.         if($control instanceof jFormsControlGroups{
  780.             foreach($control->getChildControls(as $ctrl)
  781.                 $this->addChildControl($ctrl);
  782.         }
  783.     }
  784.  
  785.     /**
  786.      * add a control to the form, before the specified control
  787.      * @param jFormsControl $control the control to add
  788.      * @param string $ref The ref of the control the new control should be inserted before
  789.      * @since 1.1
  790.      */
  791.     public function addControlBefore($control$ref){
  792.         if(isset($this->rootControls[$ref])){
  793.             $controls array();
  794.             foreach($this->rootControls as $k=>$c){
  795.                 if($k == $ref)
  796.                     $controls[$control->refnull;
  797.                 $controls[$k$c;
  798.             }
  799.             $this->rootControls $controls;
  800.         }
  801.         $this->addControl($control);
  802.     }
  803.  
  804.  
  805.     function removeControl($name{
  806.         if(!isset($this->rootControls [$name]))
  807.             return;
  808.         unset($this->rootControls [$name]);
  809.         unset($this->controls [$name]);
  810.         unset($this->submits [$name]);
  811.         if($this->reset && $this->reset->ref == $name)
  812.             $this->reset = null;
  813.         unset($this->uploads [$name]);
  814.         unset($this->hiddens [$name]);
  815.         unset($this->htmleditors [$name]);
  816.         unset($this->wikieditors [$name]);
  817.         unset($this->container->data[$name]);
  818.     }
  819.  
  820.  
  821.     /**
  822.     * declare a child control to the form. The given control should be a child of an other control
  823.     * @param jFormsControl $control 
  824.     */
  825.     public function addChildControl($control){
  826.         $this->controls [$control->ref$control;
  827.         switch ($control->type{
  828.             case 'submit':
  829.                 $this->submits [$control->ref$control;
  830.                 break;
  831.             case 'reset':
  832.                 $this->reset = $control;
  833.                 break;
  834.             case 'upload':
  835.                 $this->uploads [$control->ref$control;
  836.                 break;
  837.             case 'hidden':
  838.                 $this->hiddens [$control->ref$control;
  839.                 break;
  840.             case 'htmleditor':
  841.                 $this->htmleditors [$control->ref$control;
  842.                 break;
  843.             case 'wikieditor':
  844.                 $this->wikieditors [$control->ref$control;
  845.                 break;
  846.         }
  847.         $control->setForm($this);
  848.  
  849.         if(!isset($this->container->data[$control->ref])){
  850.             if $control->datatype instanceof jDatatypeDateTime && $control->defaultValue == 'now'{
  851.                 $dt new jDateTime();
  852.                 $dt->now();
  853.                 $this->container->data[$control->ref$dt->toString($control->datatype->getFormat());
  854.             }
  855.             else {
  856.                 $this->container->data[$control->ref$control->defaultValue;
  857.             }
  858.         }
  859.     }
  860.  
  861.     /**
  862.      * generate a new token for security against CSRF
  863.      * a builder should call it and create for example an hidden input
  864.      * so jForms could verify it after the submit.
  865.      * @return string the token
  866.      * @since 1.1.2
  867.      */
  868.     public function createNewToken({
  869.       if ($this->container->token == ''{
  870.           $tok md5($this->container->formId.time().session_id());
  871.           return ($this->container->token $tok);
  872.       }
  873.       return $this->container->token;
  874.     }
  875. }

Documentation generated on Wed, 04 Jan 2017 22:54:20 +0100 by phpDocumentor 1.4.3