Source for file jFormsBase.class.php
Documentation is available at jFormsBase.class.php
- <?php
- /**
- * @package jelix
- * @subpackage forms
- * @author Laurent Jouanneau
- * @contributor Dominique Papin
- * @contributor Christophe Thiriot
- * @copyright 2006-2007 Laurent Jouanneau, 2007 Dominique Papin
- * @link http://www.jelix.org
- * @licence http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public Licence, see LICENCE file
- */
-
- /**
- *
- */
- require(JELIX_LIB_FORMS_PATH.'jFormsControl.class.php');
- require(JELIX_LIB_FORMS_PATH.'jFormsDatasource.class.php');
- require(JELIX_LIB_UTILS_PATH.'jDatatype.class.php');
-
- /**
- * exception for jforms
- * @package jelix
- * @subpackage forms
- */
- class jExceptionForms extends jException {
-
- }
-
- /**
- * base class of all form classes generated by the jform compiler
- * @package jelix
- * @subpackage forms
- */
- abstract class jFormsBase {
-
- /**
- * List of all form controls
- * array of jFormsControl objects
- * @var array
- * @see jFormsControl
- */
- protected $_controls = array();
-
- /**
- * List of submit buttons
- * array of jFormsControl objects
- * @var array
- * @see jFormsControl
- */
- protected $_submits = array();
-
- /**
- * Reset button
- * @var jFormsControl
- * @see jFormsControl
- * @since 1.0
- */
- protected $_reset = null;
-
- /**
- * List of uploads controls
- * array of jFormsControl objects
- * @var array
- * @see jFormsControl
- */
- protected $_uploads = array();
-
- /**
- * the data container
- * @var jFormsDataContainer
- */
- protected $_container=null;
-
- /**
- * content list of available form builder
- * @var boolean
- */
- protected $_builders = array();
-
- /**
- * the form selector
- * @var string
- */
- protected $_sel;
-
- /**
- * @param string $sel the form selector
- * @param jFormsDataContainer $container the data container
- * @param boolean $reset says if the data should be reset
- */
- public function __construct($sel, &$container, $reset = false){
- $this->_container = & $container;
- if($reset){
- $this->_container->clear();
- }
- $this->_sel = $sel;
- }
-
- /**
- * set form data from request parameters
- */
- public function initFromRequest(){
- $req = $GLOBALS['gJCoord']->request;
- foreach($this->_controls as $name=>$ctrl){
- if($ctrl->readonly) continue;
- $value = $req->getParam($name);
- //@todo à prevoir un meilleur test, pour les formulaires sur plusieurs pages
- if($value === null) $value='';
- if($ctrl->type=='checkbox'){
- if($value){
- $value = $ctrl->valueOnCheck;
- }else{
- $value = $ctrl->valueOnUncheck;
- }
- }elseif($ctrl->type=='upload'){
- if(isset($_FILES[$name])){
- $value = $_FILES[$name]['name'];
- }else{
- $value= '';
- }
- }elseif($ctrl->type=='submit' && $value && !$ctrl->standalone) {
- // because IE send the <button> content as value instead of the content of the
- // "value" attribute, we should verify it and get the real value
- // or when using <input type="submit">, we have only the label as value (in all browsers...
- $datas = $ctrl->datasource->getDatas();
- if(!isset($datas[$value])) {
- $datas=array_flip($datas);
- if(isset($datas[$value])) {
- $value = $datas[$value];
- }
- }
- }
- $this->_container->datas[$name] = $value;
- }
- }
-
- /**
- * check validity of all data form
- * @return boolean true if all is ok
- */
- public function check(){
- $this->_container->errors = array();
- foreach($this->_controls as $name=>$ctrl){
- $err = $ctrl->check($this->_container->datas[$name], $this);
- if($err !== null)
- $this->_container->errors[$name]= $err;
- }
- return count($this->_container->errors) == 0;
- }
-
- /**
- * set form data from a DAO
- * @param string $daoSelector the selector of a dao file
- * @param string $key the primary key for the dao. if null, takes the form ID as primary key
- * @param string $dbProfil the jDb profil to use with the dao
- * @see jDao
- */
- public function initFromDao($daoSelector, $key = null, $dbProfil=''){
- if($key === null)
- $key = $this->_container->formId;
- $dao = jDao::create($daoSelector, $dbProfil);
- $daorec = $dao->get($key);
- if(!$daorec) {
- if(is_array($key))
- $key = var_export($key,true);
- throw new jExceptionForms('jelix~formserr.bad.formid.for.dao',
- array($daoSelector, $key, $this->_sel));
- }
-
- $prop = $dao->getProperties();
- foreach($this->_controls as $name=>$ctrl){
- if(isset($prop[$name])) {
- if($ctrl->datatype instanceof jDatatypeLocaleDateTime
- && $prop[$name]['datatype'] == 'datetime') {
- if($daorec->$name != '') {
- $dt = new jDateTime();
- $dt->setFromString($daorec->$name, jDateTime::DB_DTFORMAT);
- $this->_container->datas[$name] = $dt->toString(jDateTime::LANG_DTFORMAT);
- } else {
- $this->_container->datas[$name] ='';
- }
- }elseif($ctrl->datatype instanceof jDatatypeLocaleDate
- && $prop[$name]['datatype'] == 'date') {
- if($daorec->$name != '') {
- $dt = new jDateTime();
- $dt->setFromString($daorec->$name, jDateTime::DB_DFORMAT);
- $this->_container->datas[$name] = $dt->toString(jDateTime::LANG_DFORMAT);
- } else {
- $this->_container->datas[$name] ='';
- }
- }elseif($ctrl->type=='checkbox' && $prop[$name]['datatype'] == 'boolean') {
- if($daorec->$name == 'TRUE'|| $daorec->$name == 't'|| $daorec->$name == '1'||$daorec->$name == true){
- $this->_container->datas[$name] = $ctrl->valueOnCheck;
- }else {
- $this->_container->datas[$name] = $ctrl->valueOnUncheck;
- }
- }else{
- $this->_container->datas[$name] = $daorec->$name;
- }
- }
- }
- }
-
- /**
- * save data using a dao.
- * it call insert or update depending the value of the formId stored in the container
- * @param string $daoSelector the selector of a dao file
- * @param string $key the primary key for the dao. if null, takes the form ID as primary key
- * @param string $dbProfil the jDb profil to use with the dao
- * @return mixed the primary key of the new record in a case of inserting
- * @see jDao
- */
- public function saveToDao($daoSelector, $key = null, $dbProfil=''){
- $dao = jDao::get($daoSelector, $dbProfil);
-
- if($key === null)
- $key = $this->_container->formId;
-
- if($key != null && ($daorec = $dao->get($key))) {
- $toInsert= false;
- }else{
- $daorec = jDao::createRecord($daoSelector, $dbProfil);
- if($key != null)
- $daorec->setPk($key);
- $toInsert= true;
- }
-
- $prop = $dao->getProperties();
- foreach($this->_controls as $name=>$ctrl){
- if(!isset($prop[$name]))
- continue;
-
- if(is_array($this->_container->datas[$name])){
- if( count ($this->_container->datas[$name]) ==1){
- $daorec->$name = $this->_container->datas[$name][0];
- }else{
- // do nothing for arrays ?
- continue;
- }
- }else{
- $daorec->$name = $this->_container->datas[$name];
- }
-
- if($daorec->$name == '' && !$prop[$name]['required']) {
- // if no value and if the property is not required, we set null to it
- $daorec->$name = null;
- }else if($daorec->$name == '' && $prop[$name]['defaultValue'] !== null
- && in_array($prop[$name]['datatype'],
- array('int','integer','double','float'))) {
- $daorec->$name = $prop[$name]['defaultValue'];
-
- }else if( $prop[$name]['datatype'] == 'boolean'){
- $daorec->$name = ($daorec->$name == '1'|| $daorec->$name == 'true'
- || $daorec->$name == 't');
-
- }else if($ctrl->datatype instanceof jDatatypeLocaleDateTime
- && $prop[$name]['datatype'] == 'datetime') {
- $dt = new jDateTime();
- $dt->setFromString($daorec->$name, jDateTime::LANG_DTFORMAT);
- $daorec->$name = $dt->toString(jDateTime::DB_DTFORMAT);
-
- }elseif($ctrl->datatype instanceof jDatatypeLocaleDate
- && $prop[$name]['datatype'] == 'date') {
- $dt = new jDateTime();
- $dt->setFromString($daorec->$name, jDateTime::LANG_DFORMAT);
- $daorec->$name = $dt->toString(jDateTime::DB_DFORMAT);
- }
- }
- if($toInsert){
- // todo : what about updating the formId with the Pk ?
- $dao->insert($daorec);
- }else{
- $dao->update($daorec);
- }
- return $daorec->getPk();
- }
-
- /**
- * set data from a DAO, in a control
- *
- * The control must be a container like checkboxes or listbox with multiple attribute.
- * The form should contain a formId
- *
- * The Dao should map to an "association table" : its primary key should be composed by
- * the primary key stored in the formId (or the given primarykey) + the field which will contain one of
- * the values of the control. If this order is not the same as defined into the dao,
- * you should provide the list of property names which corresponds to the primary key
- * in this order : properties for the formId, followed by the property which contains
- * the value.
- * @param string $controlName the name of the control
- * @param string $daoSelector the selector of a dao file
- * @param mixed $primaryKey the primary key if the form have no id. (optional)
- * @param mixed $primaryKeyNames list of field corresponding to primary keys (optional)
- * @param string $dbProfil the jDb profil to use with the dao
- * @see jDao
- */
- public function initControlFromDao($controlName, $daoSelector, $primaryKey = null, $primaryKeyNames=null, $dbProfil=''){
-
- if(!$this->_controls[$controlName]->isContainer()){
- throw new jExceptionForms('jelix~formserr.control.not.container', array($controlName, $this->_sel));
- }
-
- if(!$this->_container->formId)
- throw new jExceptionForms('jelix~formserr.formid.undefined.for.dao', array($controlName, $this->_sel));
-
- if($primaryKey === null)
- $primaryKey = $this->_container->formId;
-
- if(!is_array($primaryKey))
- $primaryKey =array($primaryKey);
-
- $dao = jDao::create($daoSelector, $dbProfil);
-
- $conditions = jDao::createConditions();
- if($primaryKeyNames)
- $pkNamelist = $primaryKeyNames;
- else
- $pkNamelist = $dao->getPrimaryKeyNames();
-
- foreach($primaryKey as $k=>$pk){
- $conditions->addCondition ($pkNamelist[$k], '=', $pk);
- }
-
- $results = $dao->findBy($conditions);
- $valuefield = $pkNamelist[$k+1];
- $val = array();
- foreach($results as $res){
- $val[]=$res->$valuefield;
- }
- $this->_container->datas[$controlName]=$val;
- }
-
-
- /**
- * save data of a control using a dao.
- *
- * The control must be a container like checkboxes or listbox with multiple attribute.
- * If the form contain a new record (no formId), you should call saveToDao before
- * in order to get a new id (the primary key of the new record), or you should get a new id
- * by an other way. then you must pass this primary key in the third argument.
- * If the form has already a formId, then it will be used as a primary key, unless
- * you give one in the third argument.
- *
- * The Dao should map to an "association table" : its primary key should be
- * the primary key stored in the formId + the field which will contain one of
- * the values of the control. If this order is not the same as defined into the dao,
- * you should provide the list of property names which corresponds to the primary key
- * in this order : properties for the formId, followed by the property which contains
- * the value.
- * All existing records which have the formid in their keys are deleted
- * before to insert new values.
- *
- * @param string $controlName the name of the control
- * @param string $daoSelector the selector of a dao file
- * @param mixed $primaryKey the primary key if the form have no id. (optional)
- * @param mixed $primaryKeyNames list of field corresponding to primary keys (optional)
- * @param string $dbProfil the jDb profil to use with the dao
- * @see jDao
- */
- public function saveControlToDao($controlName, $daoSelector, $primaryKey = null, $primaryKeyNames=null, $dbProfil=''){
-
- if(!$this->_controls[$controlName]->isContainer()){
- throw new jExceptionForms('jelix~formserr.control.not.container', array($controlName, $this->_sel));
- }
-
- $values = $this->_container->datas[$controlName];
- if(!is_array($values) && $values != '')
- throw new jExceptionForms('jelix~formserr.value.not.array', array($controlName, $this->_sel));
-
- if(!$this->_container->formId && !$primaryKey)
- throw new jExceptionForms('jelix~formserr.formid.undefined.for.dao', array($controlName, $this->_sel));
-
- if($primaryKey === null)
- $primaryKey = $this->_container->formId;
-
- if(!is_array($primaryKey))
- $primaryKey =array($primaryKey);
-
- $dao = jDao::create($daoSelector, $dbProfil);
- $daorec = jDao::createRecord($daoSelector, $dbProfil);
-
- $conditions = jDao::createConditions();
- if($primaryKeyNames)
- $pkNamelist = $primaryKeyNames;
- else
- $pkNamelist = $dao->getPrimaryKeyNames();
-
- foreach($primaryKey as $k=>$pk){
- $conditions->addCondition ($pkNamelist[$k], '=', $pk);
- $daorec->{$pkNamelist[$k]} = $pk;
- }
-
- $dao->deleteBy($conditions);
- if (is_array($values)) {
- $valuefield = $pkNamelist[$k+1];
- foreach($values as $value){
- $daorec->$valuefield = $value;
- $dao->insert($daorec);
- }
- }
- }
-
- /**
- * method not implemented...
- * @param boolean $r
- * @deprecated since 1.0.4
- */
- public function setReadOnly($r = true){ }
-
- /**
- * return list of errors found during the check
- * @return array
- * @see jFormsBase::check
- */
- public function getErrors(){ return $this->_container->errors; }
-
- /**
- * set an error message on a specific field
- * @param string $field the field name
- * @param string $mesg the error message string
- */
- public function setErrorOn($field, $mesg){
- $this->_container->errors[$field]=$mesg;
- }
-
- /**
- *
- * @param string $name the name of the control/data
- * @param string $value the data value
- */
- public function setData($name,$value){
- if($this->_controls[$name]->type == 'checkbox') {
- if($value != $this->_controls[$name]->valueOnCheck){
- if($value =='on')
- $value = $this->_controls[$name]->valueOnCheck;
- else
- $value = $this->_controls[$name]->valueOnUncheck;
- }
- }
- $this->_container->datas[$name]=$value;
- }
- /**
- *
- * @param string $name the name of the control/data
- * @return string the data value
- */
- public function getData($name){
- if(isset($this->_container->datas[$name]))
- return $this->_container->datas[$name];
- else return null;
- }
-
- /**
- * @return array form data
- */
- public function getDatas(){ return $this->_container->datas; }
- /**
- * @return jFormsDataContainer
- */
- public function getContainer(){ return $this->_container; }
-
- /**
- * @return array of jFormsControl objects
- */
- public function getControls(){ return $this->_controls; }
-
- /**
- * @param string $name the control name you want to get
- * @return jFormsControl
- * @since jelix 1.0
- */
- public function getControl($name){ return $this->_controls[$name]; }
-
- /**
- * @return array of jFormsControl objects
- */
- public function getSubmits(){ return $this->_submits; }
-
- /**
- * @return array of jFormsControl objects
- */
- public function getReset(){ return $this->_reset; }
-
- /**
- * @return string the formId
- */
- public function id(){ return $this->_container->formId; }
-
- /**
- * @return boolean
- */
- public function hasUpload() { return count($this->_uploads)>0; }
-
- /**
- * @param string $buildertype the type name of a form builder
- * @param string $action action selector where form will be submit
- * @param array $actionParams parameters for the action
- * @return jFormsBuilderBase
- */
- public function getBuilder($buildertype, $action, $actionParams){
- if(isset($this->_builders[$buildertype])){
- include_once(JELIX_LIB_FORMS_PATH.'jFormsBuilderBase.class.php');
- include_once ($this->_builders[$buildertype][0]);
- $c = $this->_builders[$buildertype][1];
- return new $c($this, $action, $actionParams);
- }else{
- throw new jExceptionForms('jelix~formserr.invalid.form.builder', array($buildertype, $this->_sel));
- }
- }
-
- /**
- * save an uploaded file in the given directory. the given control must be
- * an upload control of course.
- * @param string $controlName the name of the upload control
- * @param string $path path of the directory where to store the file. If it is not given,
- * it will be stored under the var/uploads/_modulename~formname_/ directory
- * @param string $alternateName a new name for the file. If it is not given, the file
- * while be stored with the original name
- * @return boolean true if the file has been saved correctly
- */
- public function saveFile($controlName, $path='', $alternateName='') {
- if ($path == '') {
- $path = JELIX_APP_VAR_PATH.'uploads/'.$this->_sel.'/';
- } else if (substr($path, -1, 1) != '/') {
- $path.='/';
- }
-
- if(!isset($this->_controls[$controlName]) || $this->_controls[$controlName]->type != 'upload')
- throw new jExceptionForms('jelix~formserr.invalid.upload.control.name', array($controlName, $this->_sel));
-
- if(!isset($_FILES[$controlName]) || $_FILES[$controlName]['error']!= UPLOAD_ERR_OK)
- return false;
-
- if($this->_controls[$controlName]->maxsize && $_FILES[$controlName]['size'] > $this->_controls[$controlName]->maxsize){
- return false;
- }
- jFile::createDir($path);
- if ($alternateName == '') {
- $path.= $_FILES[$controlName]['name'];
- } else {
- $path.= $alternateName;
- }
- return move_uploaded_file($_FILES[$controlName]['tmp_name'], $path);
- }
-
- /**
- * save all uploaded file in the given directory
- * @param string $path path of the directory where to store the file. If it is not given,
- * it will be stored under the var/uploads/_modulename~formname_/ directory
- */
- public function saveAllFiles($path='') {
- if ($path == '') {
- $path = JELIX_APP_VAR_PATH.'uploads/'.$this->_sel.'/';
- } else if (substr($path, -1, 1) != '/') {
- $path.='/';
- }
-
- if(count($this->_uploads))
- jFile::createDir($path);
-
- foreach($this->_uploads as $ref=>$ctrl){
-
- if(!isset($_FILES[$ref]) || $_FILES[$ref]['error']!= UPLOAD_ERR_OK)
- continue;
- if($ctrl->maxsize && $_FILES[$ref]['size'] > $ctrl->maxsize)
- continue;
-
- move_uploaded_file($_FILES[$ref]['tmp_name'], $path.$_FILES[$ref]['name']);
- }
- }
-
-
- /**
- * add a control to the form
- * @param $control jFormsControl
- */
- protected function addControl($control){
- $this->_controls [$control->ref] = $control;
- if($control->type =='submit')
- $this->_submits [$control->ref] = $control;
- else if($control->type =='reset')
- $this->_reset = $control;
- else if($control->type =='upload')
- $this->_uploads [$control->ref] = $control;
-
- if(!isset($this->_container->datas[$control->ref])){
- if ( $control->datatype instanceof jDatatypeDateTime && $control->defaultValue == 'now') {
- $dt = new jDateTime();
- $dt->now();
- $this->_container->datas[$control->ref] = $dt->toString($control->datatype->getFormat());
- }
- else {
- $this->_container->datas[$control->ref] = $control->defaultValue;
- }
- }
- }
- }
-
- ?>
Documentation generated on Wed, 07 Sep 2011 13:47:22 +0200 by phpDocumentor 1.4.3