diff --git a/gulliver/system/class.dvEditor.php b/gulliver/system/class.dvEditor.php index 14bac5de2..af447c5ab 100755 --- a/gulliver/system/class.dvEditor.php +++ b/gulliver/system/class.dvEditor.php @@ -1,11 +1,13 @@ . - * - * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * along with this program. If not, see . + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., * Coral Gables, FL, 33134, USA, or email info@colosa.com. - * + * */ //XmlForm_Field_DVEditor - /** +/** * XmlForm_Field_HTML class definition * It is useful to see dynaforms how are built + * * @package gulliver.system - * @author + * @author + * * @copyright (C) 2002 by Colosa Development Team. * */ class XmlForm_Field_HTML extends XmlForm_Field { - var $toolbarSet = 'smallToolBar'; - var $width = '100%'; - var $height = '200' ; - var $defaultValue ='
'; - - /** - * render function is drawing the dynaform - * @author - * - * @access public - * @param string $value - * @param string $owner - * @return string - * - */ - function render( $value , $owner=NULL ) { - $value = ($value=='')?'
':$value; - $html = "
" ; - $html .= ""; - $html .= "
"; - return $html; - } - - /** - * attachEvents function is putting its events - * @author - * - * @access public - * @param string $element - * @return string - * - */ - function attachEvents($element) { - - $html='window._editor'.$this->name.'=new DVEditor(getField("'.$this->name.'").parentNode,getField("'.$this->name.'").value,element,"' . $this->height . '","'.$this->mode.'");'; - if($this->mode=="edit") - $html.='window._editor'.$this->name.'.loadToolBar("/js/dveditor/core/toolbars/'.$this->toolbarSet.'.html");'; - $html.='window._editor'.$this->name.'.syncHidden("window._editor'.$this->name.'");'; - return $html; - } + public $toolbarSet = 'smallToolBar'; + public $width = '100%'; + public $height = '200'; + public $defaultValue = '
'; + + /** + * render function is drawing the dynaform + * + * @author + * + * + * @access public + * @param string $value + * @param string $owner + * @return string + * + */ + public function render ($value, $owner = null) + { + $value = ($value == '') ? '
' : $value; + $html = "
"; + $html .= ""; + $html .= "
"; + return $html; + } + + /** + * attachEvents function is putting its events + * + * @author + * + * + * @access public + * @param string $element + * @return string + * + */ + public function attachEvents ($element) + { + $html = 'window._editor' . $this->name . '=new DVEditor(getField("' . $this->name . '").parentNode,getField("' . $this->name . '").value,element,"' . $this->height . '","' . $this->mode . '");'; + if ($this->mode == "edit") { + $html .= 'window._editor' . $this->name . '.loadToolBar("/js/dveditor/core/toolbars/' . $this->toolbarSet . '.html");'; + } + $html .= 'window._editor' . $this->name . '.syncHidden("window._editor' . $this->name . '");'; + return $html; + } } + diff --git a/gulliver/system/class.error.php b/gulliver/system/class.error.php index b2301dbf8..04a454de5 100755 --- a/gulliver/system/class.error.php +++ b/gulliver/system/class.error.php @@ -1,11 +1,12 @@ . - * - * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * along with this program. If not, see . + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., * Coral Gables, FL, 33134, USA, or email info@colosa.com. - * + * */ /** + * * @package gulliver.system -*/ + * + */ require_once 'PEAR.php'; /** * G_Error implements a class for reporting portable database error * messages + */ + +define( 'G_ERROR', - 100 ); +define( 'DB_ERROR_FEATURE_NOT_AVAILABLE', - 101 ); +define( 'DB_ERROR_OBJECT_NOT_DEFINED', - 102 ); +define( 'G_ERROR_WARNING_MESSAGE', - 103 ); +define( 'G_ERROR_DBCONNECTION', - 104 ); +define( 'G_ERROR_SYSTEM_UID', - 105 ); +define( 'G_ERROR_SYSTEM_CODE', - 106 ); +define( 'G_ERROR_ROLE_UID', - 107 ); +define( 'G_ERROR_ROLE_CODE', - 108 ); +define( 'G_ERROR_PERMISSION_UID', - 109 ); +define( 'G_ERROR_PERMISSION_CODE', - 110 ); +define( 'G_ERROR_USER_UID', - 111 ); +define( 'G_ERROR_USER_USERNAME', - 112 ); +define( 'G_ERROR_USERNAME_EMPTY', - 113 ); +define( 'G_ERROR_PASSWORD_EMPTY', - 114 ); +define( 'G_ERROR_PASSWORD_INCORRECT', - 115 ); +define( 'G_ERROR_USER_INACTIVE', - 116 ); +define( 'G_ERROR_DUE_DATE', - 117 ); +define( 'G_ERROR_ALREADY_ASSIGNED', - 118 ); + +/** + * + * @package gulliver.system * */ -define('G_ERROR', -100); -define('DB_ERROR_FEATURE_NOT_AVAILABLE', -101); -define('DB_ERROR_OBJECT_NOT_DEFINED', -102); -define('G_ERROR_WARNING_MESSAGE', -103); -define('G_ERROR_DBCONNECTION', -104); -define('G_ERROR_SYSTEM_UID', -105); -define('G_ERROR_SYSTEM_CODE', -106); -define('G_ERROR_ROLE_UID', -107); -define('G_ERROR_ROLE_CODE', -108); -define('G_ERROR_PERMISSION_UID', -109); -define('G_ERROR_PERMISSION_CODE', -110); -define('G_ERROR_USER_UID', -111); -define('G_ERROR_USER_USERNAME', -112); -define('G_ERROR_USERNAME_EMPTY', -113); -define('G_ERROR_PASSWORD_EMPTY', -114); -define('G_ERROR_PASSWORD_INCORRECT', -115); -define('G_ERROR_USER_INACTIVE', -116); -define('G_ERROR_DUE_DATE', -117); -define('G_ERROR_ALREADY_ASSIGNED', -118); - -/** - * @package gulliver.system -*/ - class G_Error extends PEAR_Error { - /** - * G_Error constructor - * - * @param mixed $code error code, or string with error message - * @param int $mode what "error mode" to operate in - * @param int $level what error level to use for $mode &PEAR_ERROR_TRIGGER - * @param mixed $debuginfo additional debug info, such as the last query - * - * @see PEAR_Error - */ - function G_Error($code = G_ERROR, $mode = PEAR_ERROR_RETURN, $level = E_USER_NOTICE, $debuginfo = null) { - if (is_int($code)) { - $this->PEAR_Error('G Error: ' . G_Error::errorMessage($code), $code, $mode, $level, $debuginfo); - } else { - $this->PEAR_Error("G Error: $code", DB_ERROR, $mode, $level, $debuginfo); + + /** + * G_Error constructor + * + * @param mixed $code error code, or string with error message + * @param int $mode what "error mode" to operate in + * @param int $level what error level to use for $mode &PEAR_ERROR_TRIGGER + * @param mixed $debuginfo additional debug info, such as the last query + * + * @see PEAR_Error + */ + public function G_Error ($code = G_ERROR, $mode = PEAR_ERROR_RETURN, $level = E_USER_NOTICE, $debuginfo = null) + { + if (is_int( $code )) { + $this->PEAR_Error( 'G Error: ' . G_Error::errorMessage( $code ), $code, $mode, $level, $debuginfo ); + } else { + $this->PEAR_Error( "G Error: $code", DB_ERROR, $mode, $level, $debuginfo ); + } } - } - /** - * this function returns the kind of Error - * @author - * @access public - * @param string $code - * @return string - * - */ - function errorMessage ( $code ) { - static $gErrorMessages; - if ( $code < 0 && $code > -100 ) { - return DB::errorMessage ( $code ); + + /** + * this function returns the kind of Error + * + * @author + * + * @access public + * @param string $code + * @return string + * + */ + public function errorMessage ($code) + { + static $gErrorMessages; + if ($code < 0 && $code > - 100) { + return DB::errorMessage( $code ); + } else { + if (! isset( $gErrorMessages )) { + $gErrorMessages = array (G_ERROR => 'unknown error',DB_ERROR_FEATURE_NOT_AVAILABLE => 'this function or feature is not available for this database engine',DB_ERROR_OBJECT_NOT_DEFINED => 'Object or variable not defined',G_ERROR_WARNING_MESSAGE => 'Warning message' + ); + } + /* + if (DB::isError($code)) { + $code = $code->getCode(); + } + */ + return isset( $gErrorMessages[$code] ) ? $gErrorMessages[$code] : (isset( $errorMessages ) ? $errorMessages['G_ERROR'] : ''); + } } - else { - if (!isset($gErrorMessages)) { - $gErrorMessages = array( - G_ERROR => 'unknown error', - DB_ERROR_FEATURE_NOT_AVAILABLE => 'this function or feature is not available for this database engine', - DB_ERROR_OBJECT_NOT_DEFINED => 'Object or variable not defined', - G_ERROR_WARNING_MESSAGE => 'Warning message', - ); - } -/* - if (DB::isError($code)) { - $code = $code->getCode(); - } - */ - return isset($gErrorMessages[$code]) ? $gErrorMessages[$code] : (isset($errorMessages) ? $errorMessages['G_ERROR'] : ''); - } - } } + diff --git a/gulliver/system/class.pagedTable.php b/gulliver/system/class.pagedTable.php index 04c424de9..54a0a866b 100755 --- a/gulliver/system/class.pagedTable.php +++ b/gulliver/system/class.pagedTable.php @@ -1,7 +1,8 @@ . + * along with this program. If not, see . * * For more information, contact Colosa Inc, 2566 Le Jeune Rd., * Coral Gables, FL, 33134, USA, or email info@colosa.com. * */ -G::LoadClass('filterForm'); -G::LoadClass('xmlMenu'); +G::LoadClass( 'filterForm' ); +G::LoadClass( 'xmlMenu' ); /** * Class pagedTable + * * @author David S. Callizaya S. * @package gulliver.system * @access public @@ -36,951 +38,1009 @@ G::LoadClass('xmlMenu'); class pagedTable { - var $xmlFormFile; - var $currentPage; - var $orderBy = ''; - var $filter = array(); - var $filterType = array(); - var $searchBy = ''; - var $fastSearch=''; - var $order = ''; - var $template='templates/paged-table.html'; - var $tpl; - var $style = array(); - var $rowsPerPage=25; - var $ownerPage; - var $popupPage; - var $popupSubmit; - var $popupWidth=450; - var $popupHeight=200; - var $ajaxServer; - var $fields; - var $query; - var $totpages; + public $xmlFormFile; + public $currentPage; + public $orderBy = ''; + public $filter = array (); + public $filterType = array (); + public $searchBy = ''; + public $fastSearch = ''; + public $order = ''; + public $template = 'templates/paged-table.html'; + public $tpl; + public $style = array (); + public $rowsPerPage = 25; + public $ownerPage; + public $popupPage; + public $popupSubmit; + public $popupWidth = 450; + public $popupHeight = 200; + public $ajaxServer; + public $fields; + public $query; + public $totpages; - //SQL QUERIES - var $sql=''; - var $sqlWhere=''; - var $sqlGroupBy=''; - var $sqlSelect='SELECT 1'; - var $sqlDelete=''; - var $sqlInsert=''; - var $sqlUpdate=''; - var $fieldDataList=''; + //SQL QUERIES + public $sql = ''; + public $sqlWhere = ''; + public $sqlGroupBy = ''; + public $sqlSelect = 'SELECT 1'; + public $sqlDelete = ''; + public $sqlInsert = ''; + public $sqlUpdate = ''; + public $fieldDataList = ''; - //Configuration - var $xmlPopup=''; - var $addRow=false; - var $deleteRow=false; - var $editRow=false; - var $notFields=' title button linknew begingrid2 endgrid2 '; // These are not considered to build the sql queries (update,insert,delete) + //Configuration + public $xmlPopup = ''; + public $addRow = false; + public $deleteRow = false; + public $editRow = false; + public $notFields = ' title button linknew begingrid2 endgrid2 '; // These are not considered to build the sql queries (update,insert,delete) - //JavaScript Object attributes - var $onUpdateField=""; - var $onDeleteField=""; - var $afterDeleteField=""; - var $onInsertField=""; - //New gulliver - var $xmlForm; - var $menu=''; - var $filterForm=''; - var $filterForm_Id=''; - var $name='pagedTable'; - var $id='A1'; - var $disableFooter = false; + //JavaScript Object attributes + public $onUpdateField = ""; + public $onDeleteField = ""; + public $afterDeleteField = ""; + public $onInsertField = ""; + + //New gulliver + public $xmlForm; + public $menu = ''; + public $filterForm = ''; + public $filterForm_Id = ''; + public $name = 'pagedTable'; + public $id = 'A1'; + public $disableFooter = false; //This attribute is used to set STYLES to groups of TD, using the field type "cellMark" (see XmlForm_Field_cellMark) - var $tdStyle=''; - var $tdClass=''; - //Config Save definition - var $__Configuration='orderBy,filter,fastSearch,style/*/showInTable';//order,rowsPerPage,disableFooter'; - - /** - * Function analizeSql - * You can to distribute the component of the query like: Select, Where, Group by and order by - * @author David S. Callizaya S. - * @access public - * @return string - */ - function analizeSql() - { - if (1===preg_match('/^\s*SELECT\s+(.+?)(?:\s+FROM\s+(.+?))(?:\s+WHERE\s+(.+?))?(?:\s+GROUP\s+BY\s+(.+?))?(?:\s+ORDER\s+BY\s+(.+?))?(?:\s+BETWEEN\s+(.+?)\s+AND\s+(.+?))?\s*$/im',$this->sqlSelect,$matches)){ - $this->sqlSelect='SELECT '.$matches[1].(($matches[2]!='')?' FROM '.$matches[2]:''); - $this->sqlSelect='SELECT '.$matches[1].(($matches[2]!='')?' FROM '.$matches[2]:''); - } - else{ - //echo('Warning: SQL Query is not well formed.'); - return; - } - $this->sqlFrom = isset($matches[2])?$matches[2]:''; - $this->sqlWhere = isset($matches[3])?$matches[3]:''; - $this->sqlGroupBy = isset($matches[4])?$matches[4]:''; - $this->sqlOrderBy = isset($matches[5])?$matches[5]:''; - $this->order=''; - if ($this->sqlOrderBy!=''){ - if ($n=preg_match_all('/\b([\w\.]+)\b(?:\s+(ASC|DESC))?,?/im',$this->sqlOrderBy,$matches,PREG_SET_ORDER)){ - for($r=0;$r < $n;$r++){ - if (!isset($matches[$r][2])) - $matches[$r][2]=''; - if ($matches[$r][2]=='') - $matches[$r][2]='ASC'; - $ord=G::createUID('',$matches[$r][1]).'='.urlencode($matches[$r][2]); - if ($this->order=='') - $this->order=$ord; - else - $this->order.='&'.$ord; - } - //Orden ascendente - if ($n==1) - $this->order=G::createUID('',$matches[0][1]) . '=' . $matches[0][2]; - } - } - //Generate: $uniqueWhere=Identify a row bys its data content - //$this->fieldDataList=url text that dentify a row bys its data content - $uniqueWhere=''; - $this->fieldDataList=''; - foreach($this->fields as $r => $field) - if ((strpos($this->notFields, ' ' . $this->fields[$r]['Type']. ' ')===FALSE)){ - if ($uniqueWhere=='') - $uniqueWhere=(($this->sqlWhere!='')?('('.$this->sqlWhere.') AND ('):'('); - else - $uniqueWhere.=' AND '; - $uniqueWhere.=$this->fields[$r]['Name'] . '=' . '@@' . $this->fields[$r]['Name']; - if ($this->fieldDataList=='') - $this->fieldDataList=''; - else - $this->fieldDataList.='&'; - $this->fieldDataList.=$this->fields[$r]['Name'] . '=' . '@@_' . $this->fields[$r]['Name']; - } - if ($uniqueWhere!='') - $uniqueWhere.=')'; - } - - /** - * Function prepareQuery - * @author David S. Callizaya S. - * @access public - * @return string - */ - function prepareQuery() - { - //DBConnection - if(!$this->sqlConnection) - $this->dbc=new DBConnection(); - else{ - if (defined('DB_' . $this->sqlConnection . '_USER')) { - if (defined('DB_' . $this->sqlConnection . '_HOST')) - eval('$res[\'DBC_SERVER\'] = DB_'.$this->sqlConnection.'_HOST;'); - else - $res['DBC_SERVER'] = DB_HOST; - if (defined('DB_' . $this->sqlConnection . '_USER')) - eval('$res[\'DBC_USERNAME\'] = DB_'.$this->sqlConnection.'_USER;'); - if (defined('DB_' . $this->sqlConnection . '_PASS')) - eval('$res[\'DBC_PASSWORD\'] = DB_'.$this->sqlConnection.'_PASS;'); - else - $res['DBC_PASSWORD'] = DB_PASS; - if (defined('DB_' . $this->sqlConnection . '_NAME')) - eval('$res[\'DBC_DATABASE\'] = DB_'.$this->sqlConnection.'_NAME;'); - else - $res['DBC_DATABASE'] = DB_NAME ; - if (defined('DB_' . $this->sqlConnection . '_TYPE')) - eval('$res[\'DBC_TYPE\'] = DB_'.$this->sqlConnection.'_TYPE;'); - else - $res['DBC_TYPE'] = defined('DB_TYPE') ? DB_TYPE : 'mysql'; - $this->dbc=new DBConnection($res['DBC_SERVER'],$res['DBC_USERNAME'],$res['DBC_PASSWORD'],$res['DBC_DATABASE'],$res['DBC_TYPE']); - } else { - $dbc=new DBConnection(); - $dbs=new DBSession($dbc); - $res=$dbs->execute("select * from DB_CONNECTION WHERE DBC_UID=".$this->sqlConnection); - $res=$res->read(); - $this->dbc=new DBConnection($res['DBC_SERVER'],$res['DBC_USERNAME'],$res['DBC_PASSWORD'],$res['DBC_DATABASE']); - } - } - $this->ses=new DBSession($this->dbc); - //Query - //Filter - if (is_array($this->filter)) { - $filterFields = $this->filter; - } else { - parse_str($this->filter,$filterFields); - } - $this->aFilter=$filterFields; - $filter=''; - foreach ($filterFields as $field => $like) - if ($like!=''){ - if ($filter!=='') - $filter.=' AND '; - if (isset($this->filterType[$field])) { - switch ($this->filterType[$field]) { - case '=': - $filter .= $field . ' = "' . mysql_real_escape_string($like) . '"'; - break; - case '<>': - $filter .= $field . ' <> "' . mysql_real_escape_string($like) . '"'; - break; - case 'contains': - $filter .= $field . ' LIKE "%' . mysql_real_escape_string($like) . '%"'; - break; - case 'like': - $filter .= $field . ' LIKE "' . mysql_real_escape_string($like) . '"'; - break; - } - } else { - $filter .= $field . ' = "' . mysql_real_escape_string($like) . '"'; - } - } - /* - * QuickSearch - */ - if ($this->searchBy!=='') { - $aSB=explode('|',$this->searchBy); - $subFilter=''; - foreach($aSB as $sBy) { - $subFilter.=($subFilter!=='')?' OR ':''; - $subFilter.=$sBy . ' LIKE "%'. - G::sqlEscape($this->fastSearch,$this->dbc->type).'%"'; - } - if ($subFilter!=='') { - $filter.=($filter!=='')?' AND ':''; - $filter.='('.$subFilter.')'; - } - } - //Merge sort array defined by USER with the array defined by SQL - parse_str($this->order,$orderFields); - parse_str($this->orderBy,$orderFields2); - //User sort is more important (first in merge). - $orderFields3 = array_merge($orderFields2, $orderFields); - //User sort is overwrites XMLs definition. - $orderFields = array_merge($orderFields3, $orderFields2); - //Order (BY SQL DEFINITION AND USER'S DEFINITION) - $this->aOrder = array(); - $order=''; - foreach ($orderFields as $field => $fieldOrder) { - $field = G::getUIDName($field,''); - $fieldOrder = strtoupper($fieldOrder); - if ($fieldOrder==='A') - $fieldOrder = 'ASC'; - if ($fieldOrder==='D') - $fieldOrder = 'DESC'; - switch ( $fieldOrder ) { - case 'ASC': - case 'DESC': - if ($order!=='') - $order.=', '; - $order .= $field . ' '. $fieldOrder; - $this->aOrder[$field] = $fieldOrder; - } - } - $this->sql=$this->sqlSelect . - ((($this->sqlWhere!='')||($filter!=''))?' WHERE ':''). - (($this->sqlWhere!='')?'('.$this->sqlWhere.')':''). - ((($this->sqlWhere!='')&&($filter!=''))?' AND ':''). - (($filter!='')?'('.$filter.')':''). - (($this->sqlGroupBy!='')?' GROUP BY '.$this->sqlGroupBy:''). - (($order!='')?' ORDER BY '.$order:''); - //$this->query=$this->ses->execute($this->sql); - //$this->totpages=ceil($this->query->count()/$this->rowsPerPage); - return; - } - - /** - * Function setupFromXmlform - * @author David S. Callizaya S. - * @access public - * @param string xmlForm - * @return string - */ - function setupFromXmlform($xmlForm) - { - $this->xmlForm = $xmlForm; - //Config - $this->name = $xmlForm->name; - $this->id = $xmlForm->id; - $this->sqlConnection=((isset($this->xmlForm->sqlConnection))?$this->xmlForm->sqlConnection:''); - if (isset($_GET['page'])) - $this->currentPage = $_GET['page']; - else - $this->currentPage = 1; - if (isset($_GET['order'])) - $this->orderBy = urldecode($_GET['order']); - else - $this->orderBy = ""; - if (isset($_GET['filter'])) - $this->filter = urldecode($_GET['filter']); - else - $this->filter = ""; - $this->ajaxServer=G::encryptLink('../gulliver/pagedTableAjax'); - $this->ownerPage=G::encryptLink(SYS_CURRENT_URI); - //Needed for $mysql_real_escape_string - $auxDbc = new DBConnection(); - if (isset($this->xmlForm->sql)) - $this->sqlSelect=G::replaceDataField($this->xmlForm->sql,$this->xmlForm->values); - else - trigger_Error('Warning: sql query is empty',E_USER_WARNING); - // Config attributes from XMLFORM file - $myAttributes=get_class_vars(get_class($this)); - foreach ($this->xmlForm->xmlform->tree->attribute as $atrib => $value) - if (array_key_exists( $atrib, $myAttributes)){ - eval('settype($value,gettype($this->'.$atrib.'));'); - if ($value!=='') - eval('$this->'.$atrib.'=$value;'); - } - //Prepare the fields - $this->style=array();$this->gridWidth="";$this->gridFields=""; - $this->fieldsType=array(); - foreach ($this->xmlForm->fields as $f => $v){ - $r=$f; - $this->fields[$r]['Name'] =$this->xmlForm->fields[$f]->name; - $this->fields[$r]['Type'] =$this->xmlForm->fields[$f]->type; - if (isset($this->xmlForm->fields[$f]->size)) - $this->fields[$r]['Size'] = $this->xmlForm->fields[$f]->size; - $this->fields[$r]['Label']=$this->xmlForm->fields[$f]->label; - } - //Autocomplete the sql queries - // Here we can to distribute the component of the query like: Select, Where, Group by and order by - $this->analizeSql(); - //Set the default settings - $this->defaultStyle(); - //continue whith the setup - $this->gridWidth=''; $this->gridFields=''; - foreach($this->xmlForm->fields as $f => $v){ - $r=$f; - //Parse the column properties - foreach ($this->xmlForm->fields[$f] as $attribute => $value){ - if (!is_object($value)) { - $this->style[$r][$attribute] = $value; - } - } - //Needed for javascript - //only the visible columns's width and name are stored - if ($this->style[$r]['showInTable']!='0'){ - $this->gridWidth.=','.$this->style[$r]['colWidth']; - $this->gridFields.=',"form['.$this->fields[$r]['Name'].']"'; - } - } - $totalWidth=0; - foreach($this->fields as $r => $rval) - if ($this->style[$r]['showInTable']!='0') - $totalWidth += $this->style[$r]['colWidth']; - $this->totalWidth = $totalWidth; - } - - /** - * Function setupFromTable - * @author David S. Callizaya S. - * @access public - * @parameter string table - * @return string - */ -// function setupFromTable($table) -// { -//// var_dump2($table); -// //Config -// $this->rowsPerPage=25; -// if (isset($_GET['page'])) -// $this->currentPage = $_GET['page']; -// else -// $this->currentPage = 1; -// if (isset($_GET['order'])) -// $this->orderBy = urldecode($_GET['order']); -// else -// $this->orderBy = ""; -// if (isset($_GET['filter'])) -// $this->filter = urldecode($_GET['filter']); -// else -// $this->filter = ""; -// $xmlPopup=''; -// $this->xmlFormFile=""; -///* if ($table->Action) -// $this->ajaxServer=G::encryptLink($table->Action); -// else*/ -// $this->ajaxServer=G::encryptLink('../gulliver/pagedTableAjax'); -// $this->popupPage = $this->ajaxServer . '?function=printForm&filename=' . urlencode($xmlPopup); -// $this->ownerPage=G::encryptLink(SYS_CURRENT_URI); -// $this->sqlConnection=''; -// if (isset($table->_source)) -// $this->sqlSelect=$table->_source; -// if (isset($table->WhereClause)){ -// if (strpos(strtoupper($table->WhereClause),'GROUP BY')!==FALSE) -// preg_match("/(.+)(GROUP BY)(.*)/",$table->WhereClause,$matches); -// else{ -// $matches[1]=$table->WhereClause;$matches[2]=''; -// } -// $this->sqlWhere=$matches[1]; -// if (strcasecmp($matches[2],'GROUP BY')==0) -// $this->sqlGroupBy=' GROUP BY '.$matches[3]; -// } -// if (strpos(strtoupper($this->sqlSelect),'WHERE')!==FALSE){ -// preg_match("/SELECT(.+)FROM(.+)WHERE(.+)/",$this->sqlSelect,$matches); -// $this->sqlSelect='SELECT '.$matches[1].' FROM '.$matches[2]; -// $this->sqlWhere=$matches[3]; -// } -// // DBConnection -// // $this->prepareQuery(); -// //Prepare the fields -// if ($table->show_nummbers=='YES'){ -// $r=-1; -// $this->fields[$r]['Name']='numberlabel'; -// $this->fields[$r]['Type']='numberlabel'; -// $this->fields[$r]['Label']='#'; -// } -// foreach ($table->Columns as $r => $value){ -// $this->fields[$r]['Name']=$value['Name']; -// $this->fields[$r]['Type']=$value['Type']; -// $this->fields[$r]['Label']=((isset($table->Labels[$r]))?$table->Labels[$r]:''); -// //Default values for Label if it was empty -// if ($this->fields[$r]['Label']=='') -// switch($table->Columns[$r]['Type']){ -// case 'image': -// case 'image-text': -// case 'jslink': -// //var_dump2($table->Columns[$r]); -// $this->fields[$r]['Label']=$value['Name']; -// } -// //Print the type of the field -// //$this->fields[$r]['Label'].='('.$this->fields[$r]['Type'].')'; -// $r++; -// } -// //Add a delete column if sqlDelete is established -// /* if ($this->sqlDelete!='') -// { -// $this->fields[$r]['Name']=''; -// $this->fields[$r]['Type']='linknew'; -// $this->fields[$r]['Label']=G::LoadXml('labels','ID_DELETE'); -// }*/ -// //Set the default settings -// $this->defaultStyle(); -// /* if ($this->sqlDelete!='') -// { -// $this->style[$r]['href']="#"; -// $this->style[$r]['onclick']="document.getElementById('pagedTable').outerHTML=ajax_function('{$this->ajaxServer}','delete','".$this->fieldDataList."');"; -// }*/ -// //Prepare the columns's properties -// if ($table->show_nummbers=='YES'){ -// $r=-1; -// $this->style[$r]['data']='@@_row__'; -// $this->style[$r]['colWidth']=30; -// } -// $this->gridWidth=''; -// $this->gridFields=''; -// foreach ($table->Columns as $r => $value){ -// //var_dump($value['Width']); -// $this->style[$r]['colWidth']=$value['Width']; -// $this->style[$r]['titleAlign']=$value['Align']; -// $this->style[$r]['href']=$value['Target']; -// // Add the row reference -// switch ($this->fields[$r]['Type']){ -// case 'image-text': -// case 'textimage': -// case 'image': -// case 'link': -// //$this->style[$r]['href'].='/@@_row__.html'; // No -// if (substr($value['Content'],0,1)=='&') -// $this->style[$r]['href'].='/@@_'.substr($value['Content'],1).'.html'; -// } -// // Extra events for each field -// $this->style[$r]['event']=$value['Extra']; -// if ($this->fields[$r]['Label']==''){ -// $this->style[$r]['titleVisibility']='0'; -// $this->fields[$r]['Label']=$this->fields[$r]['Name']; -// } -// //if ($value['orderByThis']===true) $this->orderBy=$value['Name']; -// //Needed for javascript -// //only the visible columns's width and name are stored -// if ($this->style[$r]['showInTable']!='0'){ -// $this->gridWidth.=','.$this->style[$r]['colWidth']; -// $this->gridFields.=',"form['.$this->fields[$r]['Name'].']"'; -// } -// $r++; -// } -// echo('
'); -//// var_dump2($this); -// } - - /** - * Function count - * @author David S. Callizaya S. - * @access public - * @return string - */ - function count() - { - $this->prepareQuery(); - return $this->query->count(); - } - - /** - * Function renderTitle - * @author David S. Callizaya S. - * @access public - * @return string - */ - function renderTitle() - { - //Render Title - $thereisnotitle=true; - foreach($this->fields as $r => $rval) - if ($this->fields[$r]['Type']==='title'){ - $this->tpl->assign( "title", $this->fields[$r]['Label']); - $thereisnotitle=false; - } - if ($thereisnotitle){ - $this->tpl->assign( "title", ' '); - } - //Render headers - $this->colCount=0; - $this->shownFields='['; - foreach($this->fields as $r => $rval) - if ($this->style[$r]['showInTable']!='0'){ - $this->tpl->newBlock( "headers" ); - $sortOrder = (((isset($this->aOrder[$this->fields[$r]['Name']])) && ($this->aOrder[$this->fields[$r]['Name']]==='ASC'))?'DESC':'ASC'); - $sortOrder = (((isset($this->aOrder[$this->fields[$r]['Name']])) && ($this->aOrder[$this->fields[$r]['Name']]==='DESC'))?'':$sortOrder); - $this->style[$r]['href'] = $this->ownerPage . '?order=' . - ($sortOrder!==''?urlencode(G::createUID('',$this->fields[$r]['Name']) . '=' . $sortOrder):'') - . '&page=' . $this->currentPage; - $this->style[$r]['onsort'] = $this->id . '.doSort("'.G::createUID('',$this->fields[$r]['Name']).'" , "'.$sortOrder.'");return false;'; - if (isset($this->style[$r]['href'])) - $this->tpl->assign( "href" , $this->style[$r]['href']); - if (isset($this->style[$r]['onsort'])) - $this->tpl->assign( "onclick" , htmlentities( $this->style[$r]['onsort'] , ENT_QUOTES, 'UTF-8' ) ); - if (isset($this->style[$r]['colWidth'])) - $this->tpl->assign( "width" , $this->style[$r]['colWidth'] ); - if (isset($this->style[$r]['colWidth'])) - $this->tpl->assign( "widthPercent" , ($this->style[$r]['colWidth']*100 / $this->totalWidth) . "%" ); - if (isset($this->style[$r]['titleAlign'])) - $this->tpl->assign( "align" , 'text-align:'.$this->style[$r]['titleAlign'].';'); - if ($this->style[$r]['titleVisibility']!='0') { - $sortOrder = (((isset($this->aOrder[$this->fields[$r]['Name']])) && ($this->aOrder[$this->fields[$r]['Name']]==='ASC'))?'b2':''); - $sortOrder = (((isset($this->aOrder[$this->fields[$r]['Name']])) && ($this->aOrder[$this->fields[$r]['Name']]==='DESC'))?'b<':$sortOrder); - $this->tpl->assign( "header" , $this->fields[$r]['Label'] . $sortOrder ); - $this->tpl->assign('displaySeparator', - (($this->colCount==0)||(!isset($this->fields[$r]['Label']))||($this->fields[$r]['Label']===''))?'display:none;':''); - } else { - $this->tpl->assign('displaySeparator','display:none;'); - } - $this->colCount+=2; - $this->shownFields.=($this->shownFields!=='[')?',':''; - $this->shownFields.='"'.$r.'"'; - } - $this->shownFields.=']'; - } - - /** - * Function renderField - * @author David S. Callizaya S. - * @access public - * @parameter string row - * @parameter string r - * @parameter string result - * @return string - */ - function renderField($row,$r,$result) - { - global $G_DATE_FORMAT; - //BEGIN: Special content: __sqlEdit__,__sqlDelete__ - $result['sqlDelete__']="pagedTable.event='Delete';pagedTable_DoIt=true;if (pagedTable.onDeleteField) pagedTable_DoIt=eval(pagedTable.onDeleteField);if (pagedTable_DoIt) document.getElementById('pagedTable').outerHTML=ajax_function('{$this->ajaxServer}','delete','field='+encodeURIComponent('".($this->fieldDataList)."'));if (pagedTable.afterDeleteField) return eval(pagedTable.afterDeleteField); else return false;"; - $result['sqlEdit__']="pagedTable.event='Update';pagedTable.field=encodeURIComponent('".$this->fieldDataList."');pagedTable.updateField(pagedTable.field);return false;"; - $result['pagedTableField__']="'".$this->fieldDataList."'"; - $result['row__']=$row; - //END: Special content. - //Merge $result with $xmlForm values (for default valuesSettings) - $result=array_merge($this->xmlForm->values,$result); - switch (true){ - case ($this->style[$r]['data']!=''): - $value = ((isset($result[$this->style[$r]['data']]))?$result[$this->style[$r]['data']]:''); - break; - default: - $value = $this->fields[$r]['Label']; - } - switch ($this->fields[$r]['Type']){ - case 'date': - /*Accept dates like 20070515 without - or / to separate its parts*/ - if (strlen ($value) <=10 && strlen ($value) > 4 ) { - $value = str_replace( '/', '-', $value); - if (strpos($value,'-')===FALSE) - $value = substr($value,0,4).'-'.substr($value,4,2).'-'.substr($value,6,2); - } - } - $this->tpl->newBlock( "field" ); - $this->tpl->assign('width', $this->style[$r]['colWidth']); - $this->tpl->assign('widthPercent', ($this->style[$r]['colWidth']*100/$this->totalWidth) . '%' ); - $this->tpl->assign('className', - (isset($this->style[$r]['colClassName']) && ($this->style[$r]['colClassName']))? - $this->style[$r]['colClassName'] : $this->tdClass); - $this->tpl->assign('style', $this->tdStyle); - if (isset($this->style[$r]['align'])) - $this->tpl->assign( "align" , $this->style[$r]['align']); - if (isset($this->style[$r]['colAlign'])) - $this->tpl->assign( "align" , $this->style[$r]['colAlign']); - /** - * BEGIN : Reeplace of @@, @%,... in field's attributes like onclick, link, - * ... - */ - if (isset($this->xmlForm->fields[ $this->fields[$r]['Name'] ]->onclick)) { - $this->xmlForm->fields[ $this->fields[$r]['Name'] ]->onclick - = G::replaceDataField($this->style[$r]['onclick'],$result); - } - if (isset($this->xmlForm->fields[ $this->fields[$r]['Name'] ]->link)) { - $this->xmlForm->fields[ $this->fields[$r]['Name'] ]->link - = G::replaceDataField($this->style[$r]['link'],$result); - } - if (isset($this->xmlForm->fields[ $this->fields[$r]['Name'] ]->value)) { - $this->xmlForm->fields[ $this->fields[$r]['Name'] ]->value - = G::replaceDataField($this->style[$r]['value'],$result); - } - /** - * BREAK : Reeplace of @@, @%,... - */ - /** - * Rendering of the field - */ - $this->xmlForm->setDefaultValues(); - $this->xmlForm->setValues( $result ); - $this->xmlForm->fields[ $this->fields[$r]['Name'] ]->mode = 'view'; - if ((array_search( 'rendergrid', get_class_methods( get_class($this->xmlForm->fields[ $this->fields[$r]['Name'] ])) )!==FALSE) - ||(array_search( 'renderGrid', get_class_methods( get_class($this->xmlForm->fields[ $this->fields[$r]['Name'] ])) )!==FALSE)) { - $htmlField = $this->xmlForm->fields[ $this->fields[$r]['Name'] ]->renderGrid( array($value) , $this->xmlForm ); - $this->tpl->assign( "value" , $htmlField[0] ); - } else { - } - /** - * CONTINUE : Reeplace of @@, @%,... - */ - if (isset($this->xmlForm->fields[ $this->fields[$r]['Name'] ]->onclick)) { - $this->xmlForm->fields[ $this->fields[$r]['Name'] ]->onclick - = $this->style[$r]['onclick']; - } - if (isset($this->xmlForm->fields[ $this->fields[$r]['Name'] ]->link)) { - $this->xmlForm->fields[ $this->fields[$r]['Name'] ]->link - = $this->style[$r]['link']; - } - if (isset($this->xmlForm->fields[ $this->fields[$r]['Name'] ]->value)) { - $this->xmlForm->fields[ $this->fields[$r]['Name'] ]->value - = $this->style[$r]['value']; - } - /** - * END : Reeplace of @@, @%,... - */ - return $this->fields[$r]['Type']; - } - - /** - * Function defaultStyle - * @author David S. Callizaya S. - * @access public - * @return string - */ - function defaultStyle() - { -// for($r=1;$r<=sizeof($this->fields);$r++) - foreach($this->fields as $r => $rval){ - $this->style[$r]=array( 'showInTable' => '1', - 'titleVisibility'=> '1', - 'colWidth' => '150', - 'onclick' => '', - 'event' => '' - ); - //Some widths - if (!(strpos(' date linknew ', ' ' . $this->fields[$r]['Type']. ' ')===FALSE)) - $this->style[$r]['colWidth']='70'; - //Data source: - if (!(strpos(' title button linknew image-text jslink ', ' ' . $this->fields[$r]['Type']. ' ')===FALSE)) - $this->style[$r]['data']=''; //If the control is a link it shows the label - else - $this->style[$r]['data']=$this->fields[$r]['Name']; //ELSE: The data value for that field - //Hidden fields - if (!isset($this->style[$r]['showInTable'])) { - if (!(strpos(' title button endgrid2 submit password ', ' ' . $this->fields[$r]['Type']. ' ')===FALSE)){ - $this->style[$r]['showInTable']='0'; - } - else{ - $this->style[$r]['showInTable']='1'; - } - } - //Hidden titles - if (!(strpos(' linknew button endgrid2 ', ' ' . $this->fields[$r]['Type']. ' ')===FALSE)){ - $this->style[$r]['titleVisibility']='0'; - } - //Align titles - $this->style[$r]['titleAlign']='center'; - //Align fields - if (isset($_SESSION['SET_DIRECTION']) && (strcasecmp($_SESSION['SET_DIRECTION'],'rtl')===0)) - $this->style[$r]['align']='right'; - else - $this->style[$r]['align']='left'; - if (!(strpos(' linknew date ', ' ' . $this->fields[$r]['Type']. ' ')===FALSE)){ - $this->style[$r]['align']='center'; - } - } - // Adjust the columns width to prevent overflow the page width - //Render headers - $totalWidth=0; - foreach($this->fields as $r => $rval) - if ($this->style[$r]['showInTable']!='0') - $totalWidth += $this->style[$r]['colWidth']; - $this->totalWidth = $totalWidth; - $maxWidth=1800; - $proportion=$totalWidth/$maxWidth; - if ($proportion>1) - $this->totalWidth = 1800; - if ($proportion>1) - foreach($this->fields as $r => $rval) - if ($this->style[$r]['showInTable']!='0') - $this->style[$r]['colWidth']=$this->style[$r]['colWidth']/$proportion; - } - - /** - * Function renderTable - * @author David S. Callizaya S. - * @param $block : = 'content'(Prints contentBlock only) - * @access public - * @return string - */ - function renderTable( $block = '' ) - { - // DBConnection - $this->prepareQuery(); - //Query for get the number of rows - $this->query=$this->ses->execute($this->sql); - $this->totRows=$this->query->count(); - $this->totpages=ceil($this->query->count()/$this->rowsPerPage); - //Query for obtain the records - $this->query=$this->ses->execute($this->sql.' LIMIT '.(($this->currentPage-1)*$this->rowsPerPage).', '.$this->rowsPerPage); - // Prepare the template - $this->tpl = new TemplatePower( PATH_CORE . $this->template ); - $this->tpl->prepare(); - /********** HEAD BLOCK ***************/ - if (($block ==='') || ($block==='head')) { - $this->tpl->newBlock('headBlock'); - $this->tpl->assign( 'pagedTable_Id' , $this->id ); - $this->tpl->assign( 'pagedTable_Name' , $this->name ); - $this->tpl->assign( 'pagedTable_Height' , $this->xmlForm->height ); - if (file_exists($this->xmlForm->home . $this->filterForm . '.xml')) { - $filterForm = new filterForm( $this->filterForm , $this->xmlForm->home ); - if ($this->menu==='') - $this->menu= 'gulliver/pagedTable_Options'; - } - if (file_exists($this->xmlForm->home . $this->menu . '.xml')) { - $menu = new xmlMenu( $this->menu , $this->xmlForm->home ); - $this->tpl->newBlock('headerBlock'); - $template = PATH_CORE . 'templates' . PATH_SEP . $menu->type . '.html'; - $menu->setValues($this->xmlForm->values); - $menu->setValues(array( 'PAGED_TABLE_ID' => $this->id )); - $menu->setValues(array( 'PAGED_TABLE_FAST_SEARCH' => $this->fastSearch )); - if (isset($filterForm->name)) { - $menu->setValues(array('SEARCH_FILTER_FORM' => $filterForm->name)); - } - $this->tpl->assign( 'content' , $menu->render( $template , $scriptCode ) ); - $oHeadPublisher =& headPublisher::getSingleton(); - $oHeadPublisher->addScriptFile( $menu->scriptURL ); - $oHeadPublisher->addScriptCode( $scriptCode ); - } - if (file_exists($this->xmlForm->home . $this->filterForm . '.xml')) { - $this->tpl->newBlock('headerBlock'); - $this->filterForm_Id = $filterForm->id; - $filterForm->type = 'filterform'; - $filterForm->ajaxServer = '../gulliver/defaultAjax'; - $template = PATH_CORE . 'templates/' . $filterForm->type . '.html'; - $filterForm->setValues($this->xmlForm->values); - $filterForm->setValues(array('PAGED_TABLE_ID' => $this->id )); - $filterForm->setValues(array( 'PAGED_TABLE_FAST_SEARCH' => $this->fastSearch )); - $this->tpl->assign( 'content' , $filterForm->render( $template , $scriptCode ) ); - $oHeadPublisher =& headPublisher::getSingleton(); - $oHeadPublisher->addScriptFile( $filterForm->scriptURL ); - $oHeadPublisher->addScriptCode( $scriptCode ); - if (isset($_SESSION)) - $_SESSION[$filterForm->id]=$filterForm->values; - } - } - /********** CONTENT BLOCK ***************/ - if (($block ==='') || ($block==='content')) { - $this->tpl->newBlock('contentBlock'); - $this->tpl->assign('gridWidth','=['. substr($this->gridWidth,1) .']'); - $this->tpl->assign('fieldNames','=['. substr($this->gridFields,1) .']'); - $this->tpl->assign('ajaxUri','="'. addslashes($this->ajaxServer) . '"'); - $this->tpl->assign('currentUri','="'. addslashes($this->ownerPage) . '"'); - $this->tpl->assign('currentOrder','="'. addslashes($this->orderBy) . '"'); - $this->tpl->assign('currentPage','='. $this->currentPage ); - $this->tpl->assign('currentFilter','="' . '"'); - $this->tpl->assign('totalRows','='.$this->query->count()); - $this->tpl->assign('rowsPerPage','='.$this->rowsPerPage); - $this->tpl->assign('popupPage','="'. addslashes($this->popupPage) . '"'); - $this->tpl->assign('popupWidth','='.$this->popupWidth); - $this->tpl->assign('popupHeight','='.$this->popupHeight); - $this->tpl->assign('pagedTable_Id', $this->id ); - $this->tpl->assign('pagedTable_Name', $this->name ); - $this->tpl->assign("pagedTable_JS" , "{$this->id}.element=document.getElementById('pagedtable[{$this->id}]');"); - $this->renderTitle(); - //Render rows - $gridRows=0; - for($j=0;$j<$this->query->count();$j++){ - $result=$this->query->read(); - //if (($j>=(($this->currentPage-1)*$this->rowsPerPage))&&($j<(($this->currentPage)*$this->rowsPerPage))) - { - $gridRows++; - $this->tpl->newBlock( "row" ); - $this->tpl->assign( "class" , "Row".(($j%2)+1)); - $this->tdStyle=''; - $this->tdClass=''; - foreach($this->fields as $r => $rval){ - if (strcasecmp($this->fields[$r]['Type'],'cellMark')==0){ - $result1=$result; - $result1['row__']=$j+1; - $this->xmlForm->setDefaultValues(); - $this->xmlForm->setValues( $result1 ); - $result1=array_merge($this->xmlForm->values,$result1); - $this->tdStyle=$this->xmlForm->fields[ $this->fields[$r]['Name'] ]->tdStyle( $result1 , $this->xmlForm ); - $this->tdClass=$this->xmlForm->fields[ $this->fields[$r]['Name'] ]->tdClass( $result1 , $this->xmlForm ); - } - elseif ($this->style[$r]['showInTable']!='0'){ - $this->renderField($j+1,$r,$result); - } - } - } - } - $this->tpl->assign('_ROOT.gridRows','='. $gridRows); //number of rows in the current page - $this->tpl->newBlock('rowTag'); - $this->tpl->assign('rowId','insertAtLast'); - if( $this->currentPage > 1 ) { - $firstUrl = $this->ownerPage . '?order=' . $this->orderBy . '&page=1'; - $firstAjax = $this->id . ".doGoToPage(1);return false;"; - $prevpage = $this->currentPage - 1; - $prevUrl = $this->ownerPage . '?order=' . $this->orderBy . '&page=' . $prevpage; - $prevAjax = $this->id . ".doGoToPage(".$prevpage.");return false;"; - $first = " "; - $prev = " "; - } - else{ - $first = " "; - $prev = " "; - } - if( $this->currentPage < $this->totpages ) { - $lastUrl = $this->ownerPage . '?order=' . $this->orderBy . '&page=' . $this->totpages; - $lastAjax = $this->id . ".doGoToPage(" .$this->totpages.");return false;"; - $nextpage = $this->currentPage + 1; - $nextUrl = $this->ownerPage . '?order=' . $this->orderBy . '&page=' . $nextpage; - $nextAjax = $this->id . ".doGoToPage(" .$nextpage.");return false;"; - $next = " "; - $last = " "; - } - else{ - $next = " "; - $last = " "; - } - $pagesEnum=''; - for ($r=1;$r<=$this->totpages;$r++) - if (($r>=($this->currentPage-5))&&($r<=($this->currentPage+5))){ - $pageAjax = $this->id . ".doGoToPage(" .$r.");return false;"; - if ($r!=$this->currentPage) - $pagesEnum.=" ownerPage . '?order=' . $this->orderBy . '&page=' . $r , ENT_QUOTES , 'utf-8' ) . "\" onclick=\"".$pageAjax."\">".$r.""; - else - $pagesEnum.=" ".$r.""; - } - if ($this->query->count()===0) { - $this->tpl->newBlock( 'norecords' ); - $this->tpl->assign( "columnCount", $this->colCount); - $noRecordsFound='ID_NO_RECORDS_FOUND'; - if (G::LoadTranslation($noRecordsFound)) $noRecordsFound = G::LoadTranslation($noRecordsFound); - $this->tpl->assign( "noRecordsFound", $noRecordsFound); - } - if (!$this->disableFooter) { - $this->tpl->newBlock( "bottomFooter" ); - $this->tpl->assign( "columnCount", $this->colCount); - $this->tpl->assign( "pagedTableId" , $this->id ); - if (($this->query->count()!==0)) { - if ($this->totpages>1){ - $this->tpl->assign( "first" , $first ); - $this->tpl->assign( "prev" , $prev ); - $this->tpl->assign( "next" , $next ); - $this->tpl->assign( "last" , $last ); - } - $this->tpl->assign( "currentPage" , $this->currentPage ); - $this->tpl->assign( "totalPages" , $this->totpages ); - $firstRow = ($this->currentPage-1) * $this->rowsPerPage+1; - $lastRow = $firstRow+$this->query->count()-1; - $this->tpl->assign( "firstRow" , $firstRow ); - $this->tpl->assign( "lastRow" , $lastRow ); - $this->tpl->assign( "totalRows" , $this->totRows ); - } else { - $this->tpl->assign( "indexStyle", 'visibility:hidden;'); - } - if ($this->searchBy) { - $this->tpl->assign( "fastSearchValue" , $this->fastSearch ); - } else { - $this->tpl->assign( "fastSearchStyle" , 'visibility:hidden;' ); - } - if ($this->addRow) - if($this->sqlInsert!='') - $this->tpl->assign( "insert" , ''./*G::LoadXml('labels','ID_ADD_NEW')*/ 'ID_ADD_NEW' .'' ); - $this->tpl->assign("pagesEnum", $pagesEnum); - } -?> - - + * @access public + * @return string + */ + public function analizeSql () + { + if (1 === preg_match( '/^\s*SELECT\s+(.+?)(?:\s+FROM\s+(.+?))(?:\s+WHERE\s+(.+?))?(?:\s+GROUP\s+BY\s+(.+?))?(?:\s+ORDER\s+BY\s+(.+?))?(?:\s+BETWEEN\s+(.+?)\s+AND\s+(.+?))?\s*$/im', $this->sqlSelect, $matches )) { + $this->sqlSelect = 'SELECT ' . $matches[1] . (($matches[2] != '') ? ' FROM ' . $matches[2] : ''); + $this->sqlSelect = 'SELECT ' . $matches[1] . (($matches[2] != '') ? ' FROM ' . $matches[2] : ''); + } else { + //echo('Warning: SQL Query is not well formed.'); + return; + } + $this->sqlFrom = isset( $matches[2] ) ? $matches[2] : ''; + $this->sqlWhere = isset( $matches[3] ) ? $matches[3] : ''; + $this->sqlGroupBy = isset( $matches[4] ) ? $matches[4] : ''; + $this->sqlOrderBy = isset( $matches[5] ) ? $matches[5] : ''; + $this->order = ''; + if ($this->sqlOrderBy != '') { + if ($n = preg_match_all( '/\b([\w\.]+)\b(?:\s+(ASC|DESC))?,?/im', $this->sqlOrderBy, $matches, PREG_SET_ORDER )) { + for ($r = 0; $r < $n; $r ++) { + if (! isset( $matches[$r][2] )) { + $matches[$r][2] = ''; + } + if ($matches[$r][2] == '') { + $matches[$r][2] = 'ASC'; + } + $ord = G::createUID( '', $matches[$r][1] ) . '=' . urlencode( $matches[$r][2] ); + if ($this->order == '') { + $this->order = $ord; + } else { + $this->order .= '&' . $ord; + } + } + //Orden ascendente + if ($n == 1) { + $this->order = G::createUID( '', $matches[0][1] ) . '=' . $matches[0][2]; + } + } + } + //Generate: $uniqueWhere=Identify a row bys its data content + //$this->fieldDataList=url text that dentify a row bys its data content + $uniqueWhere = ''; + $this->fieldDataList = ''; + foreach ($this->fields as $r => $field) { + if ((strpos( $this->notFields, ' ' . $this->fields[$r]['Type'] . ' ' ) === false)) { + if ($uniqueWhere == '') { + $uniqueWhere = (($this->sqlWhere != '') ? ('(' . $this->sqlWhere . ') AND (') : '('); + } else { + $uniqueWhere .= ' AND '; + } + $uniqueWhere .= $this->fields[$r]['Name'] . '=' . '@@' . $this->fields[$r]['Name']; + if ($this->fieldDataList == '') { + $this->fieldDataList = ''; + } else { + $this->fieldDataList .= '&'; + } + $this->fieldDataList .= $this->fields[$r]['Name'] . '=' . '@@_' . $this->fields[$r]['Name']; + } + } + if ($uniqueWhere != '') { + $uniqueWhere .= ')'; + } } - /********** CLOSE BLOCK ***************/ - if (($block ==='') || ($block==='close')) { - $this->tpl->newBlock( "closeBlock" ); + + /** + * Function prepareQuery + * + * @author David S. Callizaya S. + * @access public + * @return string + */ + public function prepareQuery () + { + //DBConnection + if (! $this->sqlConnection) { + $this->dbc = new DBConnection(); + } else { + if (defined( 'DB_' . $this->sqlConnection . '_USER' )) { + if (defined( 'DB_' . $this->sqlConnection . '_HOST' )) { + eval( '$res[\'DBC_SERVER\'] = DB_' . $this->sqlConnection . '_HOST;' ); + } else { + $res['DBC_SERVER'] = DB_HOST; + } + if (defined( 'DB_' . $this->sqlConnection . '_USER' )) { + eval( '$res[\'DBC_USERNAME\'] = DB_' . $this->sqlConnection . '_USER;' ); + } + if (defined( 'DB_' . $this->sqlConnection . '_PASS' )) { + eval( '$res[\'DBC_PASSWORD\'] = DB_' . $this->sqlConnection . '_PASS;' ); + } else { + $res['DBC_PASSWORD'] = DB_PASS; + } + if (defined( 'DB_' . $this->sqlConnection . '_NAME' )) { + eval( '$res[\'DBC_DATABASE\'] = DB_' . $this->sqlConnection . '_NAME;' ); + } else { + $res['DBC_DATABASE'] = DB_NAME; + } + if (defined( 'DB_' . $this->sqlConnection . '_TYPE' )) { + eval( '$res[\'DBC_TYPE\'] = DB_' . $this->sqlConnection . '_TYPE;' ); + } else { + $res['DBC_TYPE'] = defined( 'DB_TYPE' ) ? DB_TYPE : 'mysql'; + } + $this->dbc = new DBConnection( $res['DBC_SERVER'], $res['DBC_USERNAME'], $res['DBC_PASSWORD'], $res['DBC_DATABASE'], $res['DBC_TYPE'] ); + } else { + $dbc = new DBConnection(); + $dbs = new DBSession( $dbc ); + $res = $dbs->execute( "select * from DB_CONNECTION WHERE DBC_UID=" . $this->sqlConnection ); + $res = $res->read(); + $this->dbc = new DBConnection( $res['DBC_SERVER'], $res['DBC_USERNAME'], $res['DBC_PASSWORD'], $res['DBC_DATABASE'] ); + } + } + $this->ses = new DBSession( $this->dbc ); + //Query + //Filter + if (is_array( $this->filter )) { + $filterFields = $this->filter; + } else { + parse_str( $this->filter, $filterFields ); + } + $this->aFilter = $filterFields; + $filter = ''; + foreach ($filterFields as $field => $like) { + if ($like != '') { + if ($filter !== '') { + $filter .= ' AND '; + } + if (isset( $this->filterType[$field] )) { + switch ($this->filterType[$field]) { + case '=': + $filter .= $field . ' = "' . mysql_real_escape_string( $like ) . '"'; + break; + case '<>': + $filter .= $field . ' <> "' . mysql_real_escape_string( $like ) . '"'; + break; + case 'contains': + $filter .= $field . ' LIKE "%' . mysql_real_escape_string( $like ) . '%"'; + break; + case 'like': + $filter .= $field . ' LIKE "' . mysql_real_escape_string( $like ) . '"'; + break; + } + } else { + $filter .= $field . ' = "' . mysql_real_escape_string( $like ) . '"'; + } + } + } + /* + * QuickSearch + */ + if ($this->searchBy !== '') { + $aSB = explode( '|', $this->searchBy ); + $subFilter = ''; + foreach ($aSB as $sBy) { + $subFilter .= ($subFilter !== '') ? ' OR ' : ''; + $subFilter .= $sBy . ' LIKE "%' . G::sqlEscape( $this->fastSearch, $this->dbc->type ) . '%"'; + } + if ($subFilter !== '') { + $filter .= ($filter !== '') ? ' AND ' : ''; + $filter .= '(' . $subFilter . ')'; + } + } + //Merge sort array defined by USER with the array defined by SQL + parse_str( $this->order, $orderFields ); + parse_str( $this->orderBy, $orderFields2 ); + //User sort is more important (first in merge). + $orderFields3 = array_merge( $orderFields2, $orderFields ); + //User sort is overwrites XMLs definition. + $orderFields = array_merge( $orderFields3, $orderFields2 ); + //Order (BY SQL DEFINITION AND USER'S DEFINITION) + $this->aOrder = array (); + $order = ''; + foreach ($orderFields as $field => $fieldOrder) { + $field = G::getUIDName( $field, '' ); + $fieldOrder = strtoupper( $fieldOrder ); + if ($fieldOrder === 'A') { + $fieldOrder = 'ASC'; + } + if ($fieldOrder === 'D') { + $fieldOrder = 'DESC'; + } + switch ($fieldOrder) { + case 'ASC': + case 'DESC': + if ($order !== '') { + $order .= ', '; + } + $order .= $field . ' ' . $fieldOrder; + $this->aOrder[$field] = $fieldOrder; + } + } + $this->sql = $this->sqlSelect . ((($this->sqlWhere != '') || ($filter != '')) ? ' WHERE ' : '') . (($this->sqlWhere != '') ? '(' . $this->sqlWhere . ')' : '') . ((($this->sqlWhere != '') && ($filter != '')) ? ' AND ' : '') . (($filter != '') ? '(' . $filter . ')' : '') . (($this->sqlGroupBy != '') ? ' GROUP BY ' . $this->sqlGroupBy : '') . (($order != '') ? ' ORDER BY ' . $order : ''); + //$this->query=$this->ses->execute($this->sql); + //$this->totpages=ceil($this->query->count()/$this->rowsPerPage); + return; + } + + /** + * Function setupFromXmlform + * + * @author David S. Callizaya S. + * @access public + * @param string xmlForm + * @return string + */ + public function setupFromXmlform ($xmlForm) + { + $this->xmlForm = $xmlForm; + //Config + $this->name = $xmlForm->name; + $this->id = $xmlForm->id; + $this->sqlConnection = ((isset( $this->xmlForm->sqlConnection )) ? $this->xmlForm->sqlConnection : ''); + if (isset( $_GET['page'] )) { + $this->currentPage = $_GET['page']; + } else { + $this->currentPage = 1; + } + if (isset( $_GET['order'] )) { + $this->orderBy = urldecode( $_GET['order'] ); + } else { + $this->orderBy = ""; + } + if (isset( $_GET['filter'] )) { + $this->filter = urldecode( $_GET['filter'] ); + } else { + $this->filter = ""; + } + $this->ajaxServer = G::encryptLink( '../gulliver/pagedTableAjax' ); + $this->ownerPage = G::encryptLink( SYS_CURRENT_URI ); + //Needed for $mysql_real_escape_string + $auxDbc = new DBConnection(); + if (isset( $this->xmlForm->sql )) { + $this->sqlSelect = G::replaceDataField( $this->xmlForm->sql, $this->xmlForm->values ); + } else { + trigger_Error( 'Warning: sql query is empty', E_USER_WARNING ); + } + // Config attributes from XMLFORM file + $myAttributes = get_class_vars( get_class( $this ) ); + foreach ($this->xmlForm->xmlform->tree->attribute as $atrib => $value) { + if (array_key_exists( $atrib, $myAttributes )) { + eval( 'settype($value,gettype($this->' . $atrib . '));' ); + if ($value !== '') { + eval( '$this->' . $atrib . '=$value;' ); + } + } + } + //Prepare the fields + $this->style = array (); + $this->gridWidth = ""; + $this->gridFields = ""; + $this->fieldsType = array (); + foreach ($this->xmlForm->fields as $f => $v) { + $r = $f; + $this->fields[$r]['Name'] = $this->xmlForm->fields[$f]->name; + $this->fields[$r]['Type'] = $this->xmlForm->fields[$f]->type; + if (isset( $this->xmlForm->fields[$f]->size )) { + $this->fields[$r]['Size'] = $this->xmlForm->fields[$f]->size; + } + $this->fields[$r]['Label'] = $this->xmlForm->fields[$f]->label; + } + //Autocomplete the sql queries + // Here we can to distribute the component of the query like: Select, Where, Group by and order by + $this->analizeSql(); + //Set the default settings + $this->defaultStyle(); + //continue whith the setup + $this->gridWidth = ''; + $this->gridFields = ''; + foreach ($this->xmlForm->fields as $f => $v) { + $r = $f; + //Parse the column properties + foreach ($this->xmlForm->fields[$f] as $attribute => $value) { + if (! is_object( $value )) { + $this->style[$r][$attribute] = $value; + } + } + //Needed for javascript + //only the visible columns's width and name are stored + if ($this->style[$r]['showInTable'] != '0') { + $this->gridWidth .= ',' . $this->style[$r]['colWidth']; + $this->gridFields .= ',"form[' . $this->fields[$r]['Name'] . ']"'; + } + } + $totalWidth = 0; + foreach ($this->fields as $r => $rval) { + if ($this->style[$r]['showInTable'] != '0') { + $totalWidth += $this->style[$r]['colWidth']; + } + } + $this->totalWidth = $totalWidth; + } + + /** + * Function setupFromTable + * + * @author David S. Callizaya S. + * @access public + * @param eter string table + * @return string + */ + // function setupFromTable($table) + // { + //// var_dump2($table); + // //Config + // $this->rowsPerPage=25; + // if (isset($_GET['page'])) + // $this->currentPage = $_GET['page']; + // else + // $this->currentPage = 1; + // if (isset($_GET['order'])) + // $this->orderBy = urldecode($_GET['order']); + // else + // $this->orderBy = ""; + // if (isset($_GET['filter'])) + // $this->filter = urldecode($_GET['filter']); + // else + // $this->filter = ""; + // $xmlPopup=''; + // $this->xmlFormFile=""; + ///* if ($table->Action) + // $this->ajaxServer=G::encryptLink($table->Action); + // else*/ + // $this->ajaxServer=G::encryptLink('../gulliver/pagedTableAjax'); + // $this->popupPage = $this->ajaxServer . '?function=printForm&filename=' . urlencode($xmlPopup); + // $this->ownerPage=G::encryptLink(SYS_CURRENT_URI); + // $this->sqlConnection=''; + // if (isset($table->_source)) + // $this->sqlSelect=$table->_source; + // if (isset($table->WhereClause)){ + // if (strpos(strtoupper($table->WhereClause),'GROUP BY')!==FALSE) + // preg_match("/(.+)(GROUP BY)(.*)/",$table->WhereClause,$matches); + // else{ + // $matches[1]=$table->WhereClause;$matches[2]=''; + // } + // $this->sqlWhere=$matches[1]; + // if (strcasecmp($matches[2],'GROUP BY')==0) + // $this->sqlGroupBy=' GROUP BY '.$matches[3]; + // } + // if (strpos(strtoupper($this->sqlSelect),'WHERE')!==FALSE){ + // preg_match("/SELECT(.+)FROM(.+)WHERE(.+)/",$this->sqlSelect,$matches); + // $this->sqlSelect='SELECT '.$matches[1].' FROM '.$matches[2]; + // $this->sqlWhere=$matches[3]; + // } + // // DBConnection + // // $this->prepareQuery(); + // //Prepare the fields + // if ($table->show_nummbers=='YES'){ + // $r=-1; + // $this->fields[$r]['Name']='numberlabel'; + // $this->fields[$r]['Type']='numberlabel'; + // $this->fields[$r]['Label']='#'; + // } + // foreach ($table->Columns as $r => $value){ + // $this->fields[$r]['Name']=$value['Name']; + // $this->fields[$r]['Type']=$value['Type']; + // $this->fields[$r]['Label']=((isset($table->Labels[$r]))?$table->Labels[$r]:''); + // //Default values for Label if it was empty + // if ($this->fields[$r]['Label']=='') + // switch($table->Columns[$r]['Type']){ + // case 'image': + // case 'image-text': + // case 'jslink': + // //var_dump2($table->Columns[$r]); + // $this->fields[$r]['Label']=$value['Name']; + // } + // //Print the type of the field + // //$this->fields[$r]['Label'].='('.$this->fields[$r]['Type'].')'; + // $r++; + // } + // //Add a delete column if sqlDelete is established + // /* if ($this->sqlDelete!='') + // { + // $this->fields[$r]['Name']=''; + // $this->fields[$r]['Type']='linknew'; + // $this->fields[$r]['Label']=G::LoadXml('labels','ID_DELETE'); + // }*/ + // //Set the default settings + // $this->defaultStyle(); + // /* if ($this->sqlDelete!='') + // { + // $this->style[$r]['href']="#"; + // $this->style[$r]['onclick']="document.getElementById('pagedTable').outerHTML=ajax_function('{$this->ajaxServer}','delete','".$this->fieldDataList."');"; + // }*/ + // //Prepare the columns's properties + // if ($table->show_nummbers=='YES'){ + // $r=-1; + // $this->style[$r]['data']='@@_row__'; + // $this->style[$r]['colWidth']=30; + // } + // $this->gridWidth=''; + // $this->gridFields=''; + // foreach ($table->Columns as $r => $value){ + // //var_dump($value['Width']); + // $this->style[$r]['colWidth']=$value['Width']; + // $this->style[$r]['titleAlign']=$value['Align']; + // $this->style[$r]['href']=$value['Target']; + // // Add the row reference + // switch ($this->fields[$r]['Type']){ + // case 'image-text': + // case 'textimage': + // case 'image': + // case 'link': + // //$this->style[$r]['href'].='/@@_row__.html'; // No + // if (substr($value['Content'],0,1)=='&') + // $this->style[$r]['href'].='/@@_'.substr($value['Content'],1).'.html'; + // } + // // Extra events for each field + // $this->style[$r]['event']=$value['Extra']; + // if ($this->fields[$r]['Label']==''){ + // $this->style[$r]['titleVisibility']='0'; + // $this->fields[$r]['Label']=$this->fields[$r]['Name']; + // } + // //if ($value['orderByThis']===true) $this->orderBy=$value['Name']; + // //Needed for javascript + // //only the visible columns's width and name are stored + // if ($this->style[$r]['showInTable']!='0'){ + // $this->gridWidth.=','.$this->style[$r]['colWidth']; + // $this->gridFields.=',"form['.$this->fields[$r]['Name'].']"'; + // } + // $r++; + // } + // echo('
'); + //// var_dump2($this); + // } + + + /** + * Function count + * + * @author David S. Callizaya S. + * @access public + * @return string + */ + public function count () + { + $this->prepareQuery(); + return $this->query->count(); + } + + /** + * Function renderTitle + * + * @author David S. Callizaya S. + * @access public + * @return string + */ + public function renderTitle () + { + //Render Title + $thereisnotitle = true; + foreach ($this->fields as $r => $rval) { + if ($this->fields[$r]['Type'] === 'title') { + $this->tpl->assign( "title", $this->fields[$r]['Label'] ); + $thereisnotitle = false; + } + } + if ($thereisnotitle) { + $this->tpl->assign( "title", ' ' ); + } + //Render headers + $this->colCount = 0; + $this->shownFields = '['; + foreach ($this->fields as $r => $rval) { + if ($this->style[$r]['showInTable'] != '0') { + $this->tpl->newBlock( "headers" ); + $sortOrder = (((isset( $this->aOrder[$this->fields[$r]['Name']] )) && ($this->aOrder[$this->fields[$r]['Name']] === 'ASC')) ? 'DESC' : 'ASC'); + $sortOrder = (((isset( $this->aOrder[$this->fields[$r]['Name']] )) && ($this->aOrder[$this->fields[$r]['Name']] === 'DESC')) ? '' : $sortOrder); + $this->style[$r]['href'] = $this->ownerPage . '?order=' . ($sortOrder !== '' ? urlencode( G::createUID( '', $this->fields[$r]['Name'] ) . '=' . $sortOrder ) : '') . '&page=' . $this->currentPage; + $this->style[$r]['onsort'] = $this->id . '.doSort("' . G::createUID( '', $this->fields[$r]['Name'] ) . '" , "' . $sortOrder . '");return false;'; + if (isset( $this->style[$r]['href'] )) { + $this->tpl->assign( "href", $this->style[$r]['href'] ); + } + if (isset( $this->style[$r]['onsort'] )) { + $this->tpl->assign( "onclick", htmlentities( $this->style[$r]['onsort'], ENT_QUOTES, 'UTF-8' ) ); + } + if (isset( $this->style[$r]['colWidth'] )) { + $this->tpl->assign( "width", $this->style[$r]['colWidth'] ); + } + if (isset( $this->style[$r]['colWidth'] )) { + $this->tpl->assign( "widthPercent", ($this->style[$r]['colWidth'] * 100 / $this->totalWidth) . "%" ); + } + if (isset( $this->style[$r]['titleAlign'] )) { + $this->tpl->assign( "align", 'text-align:' . $this->style[$r]['titleAlign'] . ';' ); + } + if ($this->style[$r]['titleVisibility'] != '0') { + $sortOrder = (((isset( $this->aOrder[$this->fields[$r]['Name']] )) && ($this->aOrder[$this->fields[$r]['Name']] === 'ASC')) ? 'b2' : ''); + $sortOrder = (((isset( $this->aOrder[$this->fields[$r]['Name']] )) && ($this->aOrder[$this->fields[$r]['Name']] === 'DESC')) ? 'b<' : $sortOrder); + $this->tpl->assign( "header", $this->fields[$r]['Label'] . $sortOrder ); + $this->tpl->assign( 'displaySeparator', (($this->colCount == 0) || (! isset( $this->fields[$r]['Label'] )) || ($this->fields[$r]['Label'] === '')) ? 'display:none;' : '' ); + } else { + $this->tpl->assign( 'displaySeparator', 'display:none;' ); + } + $this->colCount += 2; + $this->shownFields .= ($this->shownFields !== '[') ? ',' : ''; + $this->shownFields .= '"' . $r . '"'; + } + } + $this->shownFields .= ']'; + } + + /** + * Function renderField + * + * @author David S. Callizaya S. + * @access public + * @param eter string row + * @param eter string r + * @param eter string result + * @return string + */ + public function renderField ($row, $r, $result) + { + global $G_DATE_FORMAT; + //BEGIN: Special content: __sqlEdit__,__sqlDelete__ + $result['sqlDelete__'] = "pagedTable.event='Delete';pagedTable_DoIt=true;if (pagedTable.onDeleteField) pagedTable_DoIt=eval(pagedTable.onDeleteField);if (pagedTable_DoIt) document.getElementById('pagedTable').outerHTML=ajax_function('{$this->ajaxServer}','delete','field='+encodeURIComponent('" . ($this->fieldDataList) . "'));if (pagedTable.afterDeleteField) return eval(pagedTable.afterDeleteField); else return false;"; + $result['sqlEdit__'] = "pagedTable.event='Update';pagedTable.field=encodeURIComponent('" . $this->fieldDataList . "');pagedTable.updateField(pagedTable.field);return false;"; + $result['pagedTableField__'] = "'" . $this->fieldDataList . "'"; + $result['row__'] = $row; + //END: Special content. + //Merge $result with $xmlForm values (for default valuesSettings) + $result = array_merge( $this->xmlForm->values, $result ); + switch (true) { + case ($this->style[$r]['data'] != ''): + $value = ((isset( $result[$this->style[$r]['data']] )) ? $result[$this->style[$r]['data']] : ''); + break; + default: + $value = $this->fields[$r]['Label']; + } + switch ($this->fields[$r]['Type']) { + case 'date': + /*Accept dates like 20070515 without - or / to separate its parts*/ + if (strlen( $value ) <= 10 && strlen( $value ) > 4) { + $value = str_replace( '/', '-', $value ); + if (strpos( $value, '-' ) === false) { + $value = substr( $value, 0, 4 ) . '-' . substr( $value, 4, 2 ) . '-' . substr( $value, 6, 2 ); + } + } + } + $this->tpl->newBlock( "field" ); + $this->tpl->assign( 'width', $this->style[$r]['colWidth'] ); + $this->tpl->assign( 'widthPercent', ($this->style[$r]['colWidth'] * 100 / $this->totalWidth) . '%' ); + $this->tpl->assign( 'className', (isset( $this->style[$r]['colClassName'] ) && ($this->style[$r]['colClassName'])) ? $this->style[$r]['colClassName'] : $this->tdClass ); + $this->tpl->assign( 'style', $this->tdStyle ); + if (isset( $this->style[$r]['align'] )) { + $this->tpl->assign( "align", $this->style[$r]['align'] ); + } + if (isset( $this->style[$r]['colAlign'] )) { + $this->tpl->assign( "align", $this->style[$r]['colAlign'] ); + } + /** + * BEGIN : Reeplace of @@, @%,... + * in field's attributes like onclick, link, + * ... + */ + if (isset( $this->xmlForm->fields[$this->fields[$r]['Name']]->onclick )) { + $this->xmlForm->fields[$this->fields[$r]['Name']]->onclick = G::replaceDataField( $this->style[$r]['onclick'], $result ); + } + if (isset( $this->xmlForm->fields[$this->fields[$r]['Name']]->link )) { + $this->xmlForm->fields[$this->fields[$r]['Name']]->link = G::replaceDataField( $this->style[$r]['link'], $result ); + } + if (isset( $this->xmlForm->fields[$this->fields[$r]['Name']]->value )) { + $this->xmlForm->fields[$this->fields[$r]['Name']]->value = G::replaceDataField( $this->style[$r]['value'], $result ); + } + /** + * BREAK : Reeplace of @@, @%,... + */ + /** + * Rendering of the field + */ + $this->xmlForm->setDefaultValues(); + $this->xmlForm->setValues( $result ); + $this->xmlForm->fields[$this->fields[$r]['Name']]->mode = 'view'; + if ((array_search( 'rendergrid', get_class_methods( get_class( $this->xmlForm->fields[$this->fields[$r]['Name']] ) ) ) !== false) || (array_search( 'renderGrid', get_class_methods( get_class( $this->xmlForm->fields[$this->fields[$r]['Name']] ) ) ) !== false)) { + $htmlField = $this->xmlForm->fields[$this->fields[$r]['Name']]->renderGrid( array ($value + ), $this->xmlForm ); + $this->tpl->assign( "value", $htmlField[0] ); + } else { + } + /** + * CONTINUE : Reeplace of @@, @%,... + */ + if (isset( $this->xmlForm->fields[$this->fields[$r]['Name']]->onclick )) { + $this->xmlForm->fields[$this->fields[$r]['Name']]->onclick = $this->style[$r]['onclick']; + } + if (isset( $this->xmlForm->fields[$this->fields[$r]['Name']]->link )) { + $this->xmlForm->fields[$this->fields[$r]['Name']]->link = $this->style[$r]['link']; + } + if (isset( $this->xmlForm->fields[$this->fields[$r]['Name']]->value )) { + $this->xmlForm->fields[$this->fields[$r]['Name']]->value = $this->style[$r]['value']; + } + /** + * END : Reeplace of @@, @%,... + */ + return $this->fields[$r]['Type']; + } + + /** + * Function defaultStyle + * + * @author David S. Callizaya S. + * @access public + * @return string + */ + public function defaultStyle () + { + // for($r=1;$r<=sizeof($this->fields);$r++) + foreach ($this->fields as $r => $rval) { + $this->style[$r] = array ('showInTable' => '1','titleVisibility' => '1','colWidth' => '150','onclick' => '','event' => '' + ); + //Some widths + if (! (strpos( ' date linknew ', ' ' . $this->fields[$r]['Type'] . ' ' ) === false)) { + $this->style[$r]['colWidth'] = '70'; + //Data source: + } + if (! (strpos( ' title button linknew image-text jslink ', ' ' . $this->fields[$r]['Type'] . ' ' ) === false)) { + $this->style[$r]['data'] = ''; //If the control is a link it shows the label + } else { + $this->style[$r]['data'] = $this->fields[$r]['Name']; //ELSE: The data value for that field + } + //Hidden fields + if (! isset( $this->style[$r]['showInTable'] )) { + if (! (strpos( ' title button endgrid2 submit password ', ' ' . $this->fields[$r]['Type'] . ' ' ) === false)) { + $this->style[$r]['showInTable'] = '0'; + } else { + $this->style[$r]['showInTable'] = '1'; + } + } + //Hidden titles + if (! (strpos( ' linknew button endgrid2 ', ' ' . $this->fields[$r]['Type'] . ' ' ) === false)) { + $this->style[$r]['titleVisibility'] = '0'; + } + //Align titles + $this->style[$r]['titleAlign'] = 'center'; + //Align fields + if (isset( $_SESSION['SET_DIRECTION'] ) && (strcasecmp( $_SESSION['SET_DIRECTION'], 'rtl' ) === 0)) { + $this->style[$r]['align'] = 'right'; + } else { + $this->style[$r]['align'] = 'left'; + } + if (! (strpos( ' linknew date ', ' ' . $this->fields[$r]['Type'] . ' ' ) === false)) { + $this->style[$r]['align'] = 'center'; + } + } + // Adjust the columns width to prevent overflow the page width + //Render headers + $totalWidth = 0; + foreach ($this->fields as $r => $rval) { + if ($this->style[$r]['showInTable'] != '0') { + $totalWidth += $this->style[$r]['colWidth']; + } + } + $this->totalWidth = $totalWidth; + $maxWidth = 1800; + $proportion = $totalWidth / $maxWidth; + if ($proportion > 1) { + $this->totalWidth = 1800; + } + if ($proportion > 1) { + foreach ($this->fields as $r => $rval) { + if ($this->style[$r]['showInTable'] != '0') { + $this->style[$r]['colWidth'] = $this->style[$r]['colWidth'] / $proportion; + } + } + } + } + + /** + * Function renderTable + * + * @author David S. Callizaya S. + * @param $block : = 'content'(Prints contentBlock only) + * @access public + * @return string + */ + public function renderTable ($block = '') + { + // DBConnection + $this->prepareQuery(); + //Query for get the number of rows + $this->query = $this->ses->execute( $this->sql ); + $this->totRows = $this->query->count(); + $this->totpages = ceil( $this->query->count() / $this->rowsPerPage ); + //Query for obtain the records + $this->query = $this->ses->execute( $this->sql . ' LIMIT ' . (($this->currentPage - 1) * $this->rowsPerPage) . ', ' . $this->rowsPerPage ); + // Prepare the template + $this->tpl = new TemplatePower( PATH_CORE . $this->template ); + $this->tpl->prepare(); + /** + * ******** HEAD BLOCK ************** + */ + if (($block === '') || ($block === 'head')) { + $this->tpl->newBlock( 'headBlock' ); + $this->tpl->assign( 'pagedTable_Id', $this->id ); + $this->tpl->assign( 'pagedTable_Name', $this->name ); + $this->tpl->assign( 'pagedTable_Height', $this->xmlForm->height ); + if (file_exists( $this->xmlForm->home . $this->filterForm . '.xml' )) { + $filterForm = new filterForm( $this->filterForm, $this->xmlForm->home ); + if ($this->menu === '') { + $this->menu = 'gulliver/pagedTable_Options'; + } + } + if (file_exists( $this->xmlForm->home . $this->menu . '.xml' )) { + $menu = new xmlMenu( $this->menu, $this->xmlForm->home ); + $this->tpl->newBlock( 'headerBlock' ); + $template = PATH_CORE . 'templates' . PATH_SEP . $menu->type . '.html'; + $menu->setValues( $this->xmlForm->values ); + $menu->setValues( array ('PAGED_TABLE_ID' => $this->id + ) ); + $menu->setValues( array ('PAGED_TABLE_FAST_SEARCH' => $this->fastSearch + ) ); + if (isset( $filterForm->name )) { + $menu->setValues( array ('SEARCH_FILTER_FORM' => $filterForm->name + ) ); + } + $this->tpl->assign( 'content', $menu->render( $template, $scriptCode ) ); + $oHeadPublisher = & headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile( $menu->scriptURL ); + $oHeadPublisher->addScriptCode( $scriptCode ); + } + if (file_exists( $this->xmlForm->home . $this->filterForm . '.xml' )) { + $this->tpl->newBlock( 'headerBlock' ); + $this->filterForm_Id = $filterForm->id; + $filterForm->type = 'filterform'; + $filterForm->ajaxServer = '../gulliver/defaultAjax'; + $template = PATH_CORE . 'templates/' . $filterForm->type . '.html'; + $filterForm->setValues( $this->xmlForm->values ); + $filterForm->setValues( array ('PAGED_TABLE_ID' => $this->id + ) ); + $filterForm->setValues( array ('PAGED_TABLE_FAST_SEARCH' => $this->fastSearch + ) ); + $this->tpl->assign( 'content', $filterForm->render( $template, $scriptCode ) ); + $oHeadPublisher = & headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile( $filterForm->scriptURL ); + $oHeadPublisher->addScriptCode( $scriptCode ); + if (isset( $_SESSION )) { + $_SESSION[$filterForm->id] = $filterForm->values; + } + } + } + /** + * ******** CONTENT BLOCK ************** + */ + if (($block === '') || ($block === 'content')) { + $this->tpl->newBlock( 'contentBlock' ); + $this->tpl->assign( 'gridWidth', '=[' . substr( $this->gridWidth, 1 ) . ']' ); + $this->tpl->assign( 'fieldNames', '=[' . substr( $this->gridFields, 1 ) . ']' ); + $this->tpl->assign( 'ajaxUri', '="' . addslashes( $this->ajaxServer ) . '"' ); + $this->tpl->assign( 'currentUri', '="' . addslashes( $this->ownerPage ) . '"' ); + $this->tpl->assign( 'currentOrder', '="' . addslashes( $this->orderBy ) . '"' ); + $this->tpl->assign( 'currentPage', '=' . $this->currentPage ); + $this->tpl->assign( 'currentFilter', '="' . '"' ); + $this->tpl->assign( 'totalRows', '=' . $this->query->count() ); + $this->tpl->assign( 'rowsPerPage', '=' . $this->rowsPerPage ); + $this->tpl->assign( 'popupPage', '="' . addslashes( $this->popupPage ) . '"' ); + $this->tpl->assign( 'popupWidth', '=' . $this->popupWidth ); + $this->tpl->assign( 'popupHeight', '=' . $this->popupHeight ); + $this->tpl->assign( 'pagedTable_Id', $this->id ); + $this->tpl->assign( 'pagedTable_Name', $this->name ); + $this->tpl->assign( "pagedTable_JS", "{$this->id}.element=document.getElementById('pagedtable[{$this->id}]');" ); + $this->renderTitle(); + //Render rows + $gridRows = 0; + for ($j = 0; $j < $this->query->count(); $j ++) { + $result = $this->query->read(); + //if (($j>=(($this->currentPage-1)*$this->rowsPerPage))&&($j<(($this->currentPage)*$this->rowsPerPage))) + //{ + $gridRows ++; + $this->tpl->newBlock( "row" ); + $this->tpl->assign( "class", "Row" . (($j % 2) + 1) ); + $this->tdStyle = ''; + $this->tdClass = ''; + foreach ($this->fields as $r => $rval) { + if (strcasecmp( $this->fields[$r]['Type'], 'cellMark' ) == 0) { + $result1 = $result; + $result1['row__'] = $j + 1; + $this->xmlForm->setDefaultValues(); + $this->xmlForm->setValues( $result1 ); + $result1 = array_merge( $this->xmlForm->values, $result1 ); + $this->tdStyle = $this->xmlForm->fields[$this->fields[$r]['Name']]->tdStyle( $result1, $this->xmlForm ); + $this->tdClass = $this->xmlForm->fields[$this->fields[$r]['Name']]->tdClass( $result1, $this->xmlForm ); + } elseif ($this->style[$r]['showInTable'] != '0') { + $this->renderField( $j + 1, $r, $result ); + } + } + //} + } + $this->tpl->assign( '_ROOT.gridRows', '=' . $gridRows ); //number of rows in the current page + $this->tpl->newBlock( 'rowTag' ); + $this->tpl->assign( 'rowId', 'insertAtLast' ); + if ($this->currentPage > 1) { + $firstUrl = $this->ownerPage . '?order=' . $this->orderBy . '&page=1'; + $firstAjax = $this->id . ".doGoToPage(1);return false;"; + $prevpage = $this->currentPage - 1; + $prevUrl = $this->ownerPage . '?order=' . $this->orderBy . '&page=' . $prevpage; + $prevAjax = $this->id . ".doGoToPage(" . $prevpage . ");return false;"; + $first = " "; + $prev = " "; + } else { + $first = " "; + $prev = " "; + } + if ($this->currentPage < $this->totpages) { + $lastUrl = $this->ownerPage . '?order=' . $this->orderBy . '&page=' . $this->totpages; + $lastAjax = $this->id . ".doGoToPage(" . $this->totpages . ");return false;"; + $nextpage = $this->currentPage + 1; + $nextUrl = $this->ownerPage . '?order=' . $this->orderBy . '&page=' . $nextpage; + $nextAjax = $this->id . ".doGoToPage(" . $nextpage . ");return false;"; + $next = " "; + $last = " "; + } else { + $next = " "; + $last = " "; + } + $pagesEnum = ''; + for ($r = 1; $r <= $this->totpages; $r ++) { + if (($r >= ($this->currentPage - 5)) && ($r <= ($this->currentPage + 5))) { + $pageAjax = $this->id . ".doGoToPage(" . $r . ");return false;"; + if ($r != $this->currentPage) { + $pagesEnum .= " ownerPage . '?order=' . $this->orderBy . '&page=' . $r, ENT_QUOTES, 'utf-8' ) . "\" onclick=\"" . $pageAjax . "\">" . $r . ""; + } else { + $pagesEnum .= " " . $r . ""; + } + } + } + if ($this->query->count() === 0) { + $this->tpl->newBlock( 'norecords' ); + $this->tpl->assign( "columnCount", $this->colCount ); + $noRecordsFound = 'ID_NO_RECORDS_FOUND'; + if (G::LoadTranslation( $noRecordsFound )) { + $noRecordsFound = G::LoadTranslation( $noRecordsFound ); + } + $this->tpl->assign( "noRecordsFound", $noRecordsFound ); + } + if (! $this->disableFooter) { + $this->tpl->newBlock( "bottomFooter" ); + $this->tpl->assign( "columnCount", $this->colCount ); + $this->tpl->assign( "pagedTableId", $this->id ); + if (($this->query->count() !== 0)) { + if ($this->totpages > 1) { + $this->tpl->assign( "first", $first ); + $this->tpl->assign( "prev", $prev ); + $this->tpl->assign( "next", $next ); + $this->tpl->assign( "last", $last ); + } + $this->tpl->assign( "currentPage", $this->currentPage ); + $this->tpl->assign( "totalPages", $this->totpages ); + $firstRow = ($this->currentPage - 1) * $this->rowsPerPage + 1; + $lastRow = $firstRow + $this->query->count() - 1; + $this->tpl->assign( "firstRow", $firstRow ); + $this->tpl->assign( "lastRow", $lastRow ); + $this->tpl->assign( "totalRows", $this->totRows ); + } else { + $this->tpl->assign( "indexStyle", 'visibility:hidden;' ); + } + if ($this->searchBy) { + $this->tpl->assign( "fastSearchValue", $this->fastSearch ); + } else { + $this->tpl->assign( "fastSearchStyle", 'visibility:hidden;' ); + } + if ($this->addRow) { + if ($this->sqlInsert != '') { + $this->tpl->assign( "insert", ''./*G::LoadXml('labels','ID_ADD_NEW')*/ 'ID_ADD_NEW' . '' ); + } + } + $this->tpl->assign( "pagesEnum", $pagesEnum ); + } + ?> + + tpl->newBlock( "closeBlock" ); + } + $this->tpl->printToScreen(); + unset( $this->tpl ); + unset( $this->dbc ); + unset( $this->ses ); + $_SESSION['pagedTable[' . $this->id . ']'] = serialize( $this ); + return; + } + + /** + * Function printForm + * + * @access public + * @param string $filename + * @param array $data + * @return void + */ + public function printForm ($filename, $data = array()) + { + // $G_FORM = new Form($filename, PATH_XMLFORM); + // echo $G_FORM->render(PATH_TPL . 'xmlform.html', $scriptContent); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent( 'xmlform', 'xmlform', $filename, '', $data, $this->popupSubmit ); + G::RenderPage( "publish", "blank" ); } - $this->tpl->printToScreen(); - unset($this->tpl); - unset($this->dbc); - unset($this->ses); - $_SESSION['pagedTable['.$this->id.']']= serialize($this); - return; - } - - /** - * Function printForm - * @access public - * @param string $filename - * @param array $data - * @return void - */ - function printForm($filename,$data=array()) - { -// $G_FORM = new Form($filename, PATH_XMLFORM); -// echo $G_FORM->render(PATH_TPL . 'xmlform.html', $scriptContent); - global $G_PUBLISH; - $G_PUBLISH = new Publisher(); - $G_PUBLISH->AddContent('xmlform', 'xmlform', $filename, '', $data , $this->popupSubmit); - G::RenderPage( "publish" , "blank" ); - } } - /** - * Function var_dump2 - * @access public - * @param string $o - * @return void - */ -function var_dump2($o) +/** + * Function var_dump2 + * + * @access public + * @param string $o + * @return void + */ +function var_dump2 ($o) { - if (is_object($o) || is_array($o)) - foreach($o as $key=>$value){ - echo(''); - var_dump($key); - echo(''); - print_r($value); - echo('
'); - } - else - var_dump($o); -} \ No newline at end of file + if (is_object( $o ) || is_array( $o )) { + foreach ($o as $key => $value) { + echo (''); + var_dump( $key ); + echo (''); + print_r( $value ); + echo ('
'); + } + } else { + var_dump( $o ); + } +} + diff --git a/gulliver/system/class.phpSqlParser.php b/gulliver/system/class.phpSqlParser.php index ed3d25648..0c0c1e941 100644 --- a/gulliver/system/class.phpSqlParser.php +++ b/gulliver/system/class.phpSqlParser.php @@ -3,179 +3,190 @@ /** * Class PHPSQLParser * Pure PHP SQL parser + * * @package gulliver.system * @access public */ -class PHPSQLParser +class PHPSQLParser { - var $reserved = array(); - var $functions = array(); + public $reserved = array (); + public $functions = array (); - function __construct($sql = false) - { - #LOAD THE LIST OF RESERVED WORDS - $this->load_reserved_words(); - if($sql) $this->parse($sql); - } - - function parse($sql) - { - $sql = trim($sql); - - #lex the SQL statement - $in = $this->split_sql($sql); - - #sometimes the parser needs to skip ahead until a particular - #token is found - $skip_until = false; - - #this is the output tree which is being parsed - $out = array(); - - #This is the last type of union used (UNION or UNION ALL) - #indicates a) presence of at least one union in this query - # b) the type of union if this is the first or last query - $union = false; - - #Sometimes a "query" consists of more than one query (like a UNION query) - #this array holds all the queries - $queries = array(); - - #This is the highest level lexical analysis. This is the part of the - #code which finds UNION and UNION ALL query parts - foreach($in as $key => $token) { - $token = trim($token); - - if($skip_until) { - if($token) { - if(strtoupper($token) == $skip_until) { - $skip_until = false; - continue; - } - } else { - continue; + function __construct ($sql = false) + { + #LOAD THE LIST OF RESERVED WORDS + $this->load_reserved_words(); + if ($sql) { + $this->parse( $sql ); } - } - - if(strtoupper($token) == "UNION") { - $union = 'UNION'; - for($i = $key + 1;$i < count($in);++$i) { - if(trim($in[$i]) == '') continue; - if(strtoupper($in[$i]) == 'ALL') { - $skip_until = 'ALL'; - $union = 'UNION ALL'; - continue ; - } else { - break; - } - } - - $queries[$union][] = $out; - $out = array(); - - } else { - $out[] = $token; - } - } - if(!empty($out)) { - if ($union) { - $queries[$union][] = $out; - } else { - $queries[] = $out; - } - } + public function parse ($sql) + { + $sql = trim( $sql ); + #lex the SQL statement + $in = $this->split_sql( $sql ); - /* MySQL supports a special form of UNION: - (select ...) - union - (select ...) + #sometimes the parser needs to skip ahead until a particular + #token is found + $skip_until = false; - This block handles this query syntax. Only one such subquery - is supported in each UNION block. (select)(select)union(select) is not legal. - The extra queries will be silently ignored. - */ - $union_types = array('UNION','UNION ALL'); - foreach($union_types as $union_type) { - if(!empty($queries[$union_type])) { - foreach($queries[$union_type] as $i => $tok_list) { - foreach($tok_list as $z => $tok) { - $tok = trim($tok); - if(!$tok) continue; - if(preg_match('/^\\(\\s*select\\s*/i', $tok)) { - $queries[$union_type][$i] = $this->parse(substr($tok, 1, -1)); - break; - } else { - $queries[$union_type][$i] = $this->process_sql($queries[$union_type][$i]); - break; + #this is the output tree which is being parsed + $out = array (); + + #This is the last type of union used (UNION or UNION ALL) + #indicates a) presence of at least one union in this query + # b) the type of union if this is the first or last query + $union = false; + + #Sometimes a "query" consists of more than one query (like a UNION query) + #this array holds all the queries + $queries = array (); + + #This is the highest level lexical analysis. This is the part of the + #code which finds UNION and UNION ALL query parts + foreach ($in as $key => $token) { + $token = trim( $token ); + + if ($skip_until) { + if ($token) { + if (strtoupper( $token ) == $skip_until) { + $skip_until = false; + continue; + } + } else { + continue; + } } - } + + if (strtoupper( $token ) == "UNION") { + $union = 'UNION'; + for ($i = $key + 1; $i < count( $in ); ++ $i) { + if (trim( $in[$i] ) == '') { + continue; + } + if (strtoupper( $in[$i] ) == 'ALL') { + $skip_until = 'ALL'; + $union = 'UNION ALL'; + continue; + } else { + break; + } + } + + $queries[$union][] = $out; + $out = array (); + + } else { + $out[] = $token; + } + } - } + + if (! empty( $out )) { + if ($union) { + $queries[$union][] = $out; + } else { + $queries[] = $out; + } + } + + /* MySQL supports a special form of UNION: + (select ...) + union + (select ...) + + This block handles this query syntax. Only one such subquery + is supported in each UNION block. (select)(select)union(select) is not legal. + The extra queries will be silently ignored. + */ + $union_types = array ('UNION','UNION ALL' + ); + foreach ($union_types as $union_type) { + if (! empty( $queries[$union_type] )) { + foreach ($queries[$union_type] as $i => $tok_list) { + foreach ($tok_list as $z => $tok) { + $tok = trim( $tok ); + if (! $tok) { + continue; + } + if (preg_match( '/^\\(\\s*select\\s*/i', $tok )) { + $queries[$union_type][$i] = $this->parse( substr( $tok, 1, - 1 ) ); + break; + } else { + $queries[$union_type][$i] = $this->process_sql( $queries[$union_type][$i] ); + break; + } + } + } + } + } + + /* If there was no UNION or UNION ALL in the query, then the query is + stored at $queries[0]. + */ + if (! empty( $queries[0] )) { + $queries[0] = $this->process_sql( $queries[0] ); + + } + + if (count( $queries ) == 1 && ! $union) { + $queries = $queries[0]; + } + + $this->parsed = $queries; + return $this->parsed; } + #This function counts open and close parenthesis and + #returns their location. This might be faster as a regex + private function count_paren ($token, $chars = array('(',')')) + { + $len = strlen( $token ); + $open = array (); + $close = array (); + for ($i = 0; $i < $len; ++ $i) { + if ($token[$i] == $chars[0]) { + $open[] = $i; + } elseif ($token[$i] == $chars[1]) { + $close[] = $i; + } - /* If there was no UNION or UNION ALL in the query, then the query is - stored at $queries[0]. - */ - if(!empty($queries[0])) { - $queries[0] = $this->process_sql($queries[0]); - + } + return array ('open' => $open,'close' => $close,'balanced' => (count( $close ) - count( $open )) + ); } - if(count($queries) == 1 && !$union) { - $queries = $queries[0]; + #This function counts open and close parenthesis and + #returns their location. This might be faster as a regex + private function count_backtick ($token) + { + $len = strlen( $token ); + $cnt = 0; + for ($i = 0; $i < $len; ++ $i) { + if ($token[$i] == '`') { + ++ $cnt; + } + } + return $cnt; } - $this->parsed = $queries; - return $this->parsed; - } + #This is the lexer + #this function splits up a SQL statement into easy to "parse" + #tokens for the SQL processor + private function split_sql ($sql) + { + if (! is_string( $sql )) { + echo "SQL:\n"; + print_r( $sql ); + exit(); + } - #This function counts open and close parenthesis and - #returns their location. This might be faster as a regex - private function count_paren($token,$chars=array('(',')')) - { - $len = strlen($token); - $open = array(); - $close = array(); - for($i = 0;$i < $len;++$i){ - if($token[$i] == $chars[0]) { - $open[] = $i; - } elseif($token[$i] == $chars[1]) { - $close[] = $i; - } - - } - return array('open' => $open, 'close' => $close, 'balanced' => ( count($close) - count($open))); - } - - #This function counts open and close parenthesis and - #returns their location. This might be faster as a regex - private function count_backtick($token) - { - $len = strlen($token); - $cnt = 0; - for($i = 0;$i < $len;++$i){ - if($token[$i] == '`') ++$cnt; - } - return $cnt; - } - - #This is the lexer - #this function splits up a SQL statement into easy to "parse" - #tokens for the SQL processor - private function split_sql($sql) - { - if(!is_string($sql)) { - echo "SQL:\n"; - print_r($sql); - exit; - } - - $sql = str_replace(array('\\\'','\\"',"\r\n","\n","()"), array("''",'""'," "," "," "), $sql); - $regex = <<=|<=|<>|>|<|&&|\|\||=|\^) |(\(.*?\)) # Match FUNCTION(...) OR BAREWORDS @@ -183,1784 +194,1212 @@ class PHPSQLParser |("(?:[^"]|"")*"+) |([^ ,]+) /ix -EOREGEX -; +EOREGEX; - $tokens = preg_split($regex, $sql, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); - $token_count = count($tokens); + $tokens = preg_split( $regex, $sql, - 1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE ); + $token_count = count( $tokens ); - /* - The above regex has one problem, because the parenthetical match is not greedy. - Thus, when matching grouped expresions such as ( (a and b) or c) the - tokenizer will produce "( (a and b)", " ", "or", " " , "c,")" + /* + The above regex has one problem, because the parenthetical match is not greedy. + Thus, when matching grouped expresions such as ( (a and b) or c) the + tokenizer will produce "( (a and b)", " ", "or", " " , "c,")" - This block detects the number of open/close parens in the given token. If the parens are balanced - (balanced == 0) then we don't need to do anything. + This block detects the number of open/close parens in the given token. If the parens are balanced + (balanced == 0) then we don't need to do anything. - otherwise, we need to balance the expression. - */ - $reset = false; - for($i = 0;$i < $token_count;++$i) { + otherwise, we need to balance the expression. + */ + $reset = false; + for ($i = 0; $i < $token_count; ++ $i) { - if(empty($tokens[$i])) continue; - - $token = $tokens[$i]; - $trim = trim($token); - if($trim) { - if($trim[0] != '(' && substr($trim, -1) == ')') { - $trim = trim(substr($trim, 0, strpos($trim, '('))); - } - $tokens[$i] = $trim; - $token = $trim; - } - - if($token && $token[0] == '(') { - $info = $this->count_paren($token); - if($info['balanced'] == 0) { - continue; - } - - #we need to find this many closing parens - $needed = abs($info['balanced']); - $n = $i; - while($needed > 0 && $n < $token_count - 1) { - ++$n; - #echo "LOOKING FORWARD TO $n [ " . $tokens[$n] . "]\n"; - $token2 = $tokens[$n]; - $info2 = $this->count_paren($token2); - $closes = count($info2['close']); - if($closes != $needed) { - $tokens[$i] .= $tokens[$n]; - unset($tokens[$n]); - $reset = true; - $info2 = $this->count_paren($tokens[$i]); - $needed = abs($info2['balanced']); - # echo "CLOSES LESS THAN NEEDED (still need $needed)\n"; - } else { - /*get the string pos of the last close paren we need*/ - $pos = $info2['close'][count($info2['close']) - 1]; - $str1 = $str2 = ""; - if($pos == 0) { - $str1 = ')'; - } else { - $str1 = substr($tokens[$n], 0, $pos) . ')'; - $str2 = substr($tokens[$n], $pos + 1); - } - #echo "CLOSES FOUND AT $n, offset:$pos [$str1] [$str2]\n"; - if(strlen($str2) > 0) { - $tokens[$n] = $str2; - } else { - unset($tokens[$n]); - $reset = true; - } - $tokens[$i] .= $str1; - $info2 = $this->count_paren($tokens[$i]); - $needed = abs($info2['balanced']); - - } - } - } - } - - #the same problem appears with backticks :( - - /* reset the array if we deleted any tokens above */ - if ($reset) $tokens = array_values($tokens); - - $token_count = count($tokens); - for($i = 0;$i < $token_count;++$i) { - if(empty($tokens[$i])) continue; - $token = $tokens[$i]; - $needed = true; - $reset = false; - if($needed && $token && strpos($token, '`') !== false) { - $info = $this->count_backtick($token); - if($info % 2 == 0) { #even number of backticks means we are balanced - continue; - } - $needed = 1; - - $n = $i; - while($needed && $n < $token_count - 1) { - $reset = true; - #echo "BACKTICK COUNT[$i]: $info old: {$tokens[$i]}, new: ($token)\n"; - ++$n; - $token .= $tokens[$n]; - unset($tokens[$n]); - $needed = $this->count_backtick($token) % 2; - } - } - if($reset) $tokens[$i] = $token; - - } - /* reset the array if we deleted any tokens above */ - $tokens = array_values($tokens); - - return $tokens; - - } - - - /** - * This function breaks up the SQL statement into logical sections. - * Some sections are then further handled by specialized functions. - */ - private function process_sql(&$tokens,$start_at = 0, $stop_at = false) - { - $prev_category = ""; - $start = microtime(true); - $token_category = ""; - - $skip_next = false; - $token_count = count($tokens); - - if(!$stop_at) { - $stop_at = $token_count; - } - - $out = false; - - for($token_number = $start_at;$token_number < $stop_at;++$token_number) { - $token = trim($tokens[$token_number]); - if($token && $token[0] == '(' && $token_category == "") { - $token_category = 'SELECT'; - } - - /* If it isn't obvious, when $skip_next is set, then we ignore the next real - token, that is we ignore whitespace. - */ - if($skip_next) { - #whitespace does not count as a next token - if($token == "") { - continue; - } - - #to skip the token we replace it with whitespace - $new_token = ""; - $skip_next = false; - } - - $upper = strtoupper($token); - switch($upper) { - - /* Tokens that get their own sections. These keywords have subclauses. */ - case 'SELECT': - case 'ORDER': - case 'LIMIT': - case 'SET': - case 'DUPLICATE': - case 'VALUES': - case 'GROUP': - case 'ORDER': - case 'HAVING': - case 'INTO': - case 'WHERE': - case 'RENAME': - case 'CALL': - case 'PROCEDURE': - case 'FUNCTION': - case 'DATABASE': - case 'SERVER': - case 'LOGFILE': - case 'DEFINER': - case 'RETURNS': - case 'EVENT': - case 'TABLESPACE': - case 'VIEW': - case 'TRIGGER': - case 'DATA': - case 'DO': - case 'PASSWORD': - case 'USER': - case 'PLUGIN': - case 'FROM': - case 'FLUSH': - case 'KILL': - case 'RESET': - case 'START': - case 'STOP': - case 'PURGE': - case 'EXECUTE': - case 'PREPARE': - case 'DEALLOCATE': - if($token == 'DEALLOCATE') { - $skip_next = true; - } - /* this FROM is different from FROM in other DML (not join related) */ - if($token_category == 'PREPARE' && $upper == 'FROM') { - continue 2; - } - - $token_category = $upper; - #$join_type = 'JOIN'; - if($upper == 'FROM' && $token_category == 'FROM') { - /* DO NOTHING*/ - } else { - continue 2; - - } - break; - - /* These tokens get their own section, but have no subclauses. - These tokens identify the statement but have no specific subclauses of their own. */ - case 'DELETE': - case 'ALTER': - case 'INSERT': - case 'REPLACE': - case 'TRUNCATE': - case 'CREATE': - case 'TRUNCATE': - case 'OPTIMIZE': - case 'GRANT': - case 'REVOKE': - case 'SHOW': - case 'HANDLER': - case 'LOAD': - case 'ROLLBACK': - case 'SAVEPOINT': - case 'UNLOCK': - case 'INSTALL': - case 'UNINSTALL': - case 'ANALZYE': - case 'BACKUP': - case 'CHECK': - case 'CHECKSUM': - case 'REPAIR': - case 'RESTORE': - case 'CACHE': - case 'DESCRIBE': - case 'EXPLAIN': - case 'USE': - case 'HELP': - $token_category = $upper; /* set the category in case these get subclauses in a future version of MySQL */ - $out[$upper][0] = $upper; - continue 2; - break; - - /* This is either LOCK TABLES or SELECT ... LOCK IN SHARE MODE*/ - case 'LOCK': - if($token_category == "") { - $token_category = $upper; - $out[$upper][0] = $upper; - } else { - $token = 'LOCK IN SHARE MODE'; - $skip_next = true; - $out['OPTIONS'][] = $token; - } - continue 2; - break; - - case 'USING': - /* USING in FROM clause is different from USING w/ prepared statement*/ - if($token_category == 'EXECUTE') { - $token_category = $upper; - continue 2; - } - if($token_category == 'FROM' && !empty($out['DELETE'])) { - $token_category = $upper; - continue 2; - } - break; - - /* DROP TABLE is different from ALTER TABLE DROP ... */ - case 'DROP': - if($token_category != 'ALTER') { - $token_category = $upper; - $out[$upper][0] = $upper; - continue 2; - } - break; - - case 'FOR': - $skip_next = true; - $out['OPTIONS'][] = 'FOR UPDATE'; - continue 2; - break; - - - case 'UPDATE': - if($token_category == "" ) { - $token_category = $upper; - continue 2; - - } - if($token_category == 'DUPLICATE') { - continue 2; - } - break; - break; - - case 'START': - $token = "BEGIN"; - $out[$upper][0] = $upper; - $skip_next = true; - break; - - /* These tokens are ignored. */ - case 'BY': - case 'ALL': - case 'SHARE': - case 'MODE': - case 'TO': - - case ';': - continue 2; - break; - - case 'KEY': - if($token_category == 'DUPLICATE') { - continue 2; - } - break; - - /* These tokens set particular options for the statement. They never stand alone.*/ - case 'DISTINCTROW': - $token = 'DISTINCT'; - case 'DISTINCT': - case 'HIGH_PRIORITY': - case 'LOW_PRIORITY': - case 'DELAYED': - case 'IGNORE': - case 'FORCE': - case 'STRAIGHT_JOIN': - case 'SQL_SMALL_RESULT': - case 'SQL_BIG_RESULT': - case 'QUICK': - case 'SQL_BUFFER_RESULT': - case 'SQL_CACHE': - case 'SQL_NO_CACHE': - case 'SQL_CALC_FOUND_ROWS': - $out['OPTIONS'][] = $upper; - continue 2; - break; - - case 'WITH': - if($token_category == 'GROUP') { - $skip_next = true; - $out['OPTIONS'][] = 'WITH ROLLUP'; - continue 2; - } - break; - - - case 'AS': - break; - - case '': - case ',': - case ';': - break; - - default: - break; - } - - if($prev_category == $token_category) { - $out[$token_category][] = $token; - } - - $prev_category = $token_category; - } - - if(!$out) return false; - - - #process the SELECT clause - if(!empty($out['SELECT'])) $out['SELECT'] = $this->process_select($out['SELECT']); - - if(!empty($out['FROM'])) $out['FROM'] = $this->process_from($out['FROM']); - if(!empty($out['USING'])) $out['USING'] = $this->process_from($out['USING']); - if(!empty($out['UPDATE'])) $out['UPDATE'] = $this->process_from($out['UPDATE']); - - if(!empty($out['GROUP'])) $out['GROUP'] = $this->process_group($out['GROUP'], $out['SELECT']); - if(!empty($out['ORDER'])) $out['ORDER'] = $this->process_group($out['ORDER'], $out['SELECT']); - - if(!empty($out['LIMIT'])) $out['LIMIT'] = $this->process_limit($out['LIMIT']); - - if(!empty($out['WHERE'])) $out['WHERE'] = $this->process_expr_list($out['WHERE']); - if(!empty($out['HAVING'])) $out['HAVING'] = $this->process_expr_list($out['HAVING']); - if(!empty($out['SET'])) $out['SET'] = $this->process_set_list($out['SET']); - if(!empty($out['DUPLICATE'])) { - $out['ON DUPLICATE KEY UPDATE'] = $this->process_set_list($out['DUPLICATE']); - unset($out['DUPLICATE']); - } - if(!empty($out['INSERT'])) $out = $this->process_insert($out); - if(!empty($out['REPLACE'])) $out = $this->process_insert($out,'REPLACE'); - if(!empty($out['DELETE'])) $out = $this->process_delete($out); - - return $out; - - } - - /** - * A SET list is simply a list of key = value expressions separated by comma (,). - * This function produces a list of the key/value expressions. - */ - private function process_set_list($tokens) - { - $column = ""; - $expression = ""; - foreach($tokens as $token) { - $token = trim($token); - if(!$column) { - if($token === false || empty($token)) continue; - $column .= $token; - continue; - } - - if($token == '=') continue; - - if($token == ',') { - $expr[] = array('column' => trim($column), 'expr' => trim($expression)); - $expression = $column = ""; - continue; - } - - $expression .= $token; - } - if($expression) { - $expr[] = array('column' => trim($column), 'expr' => trim($expression)); - } - - return $expr; - } - - /** - * This function processes the LIMIT section. - * start,end are set. If only end is provided in the query - * then start is set to 0. - */ - private function process_limit($tokens) - { - $start = 0; - $end = 0; - - if($pos = array_search(',', $tokens)) { - for($i = 0;$i < $pos;++$i) { - if($tokens[$i] != '') { - $start = $tokens[$i]; - break; - } - } - $pos = $pos + 1; - - } else { - $pos = 0; - } - - for($i = $pos;$i < count($tokens);++$i) { - if($tokens[$i] != '') { - $end = $tokens[$i]; - break; - } - } - - return array('start' => $start, 'end' => $end); - } - - /* This function processes the SELECT section. It splits the clauses at the commas. - * Each clause is then processed by process_select_expr() and the results are added to - * the expression list. - * - * Finally, at the end, the epxression list is returned. - */ - private function process_select(&$tokens) - { - $expression = ""; - $expr = array(); - foreach($tokens as $token) { - if($token == ',') { - $expr[] = $this->process_select_expr(trim($expression)); - $expression = ""; - } else { - if($token === "" || $token === false) $token = " "; - $expression .= $token ; - } - } - if($expression) $expr[] = $this->process_select_expr(trim($expression)); - return $expr; - } - - /** - * This fuction processes each SELECT clause. We determine what (if any) alias - * is provided, and we set the type of expression. - */ - private function process_select_expr($expression) - { - $capture = false; - $alias = ""; - $base_expression = $expression; - $upper = trim(strtoupper($expression)); - #if necessary, unpack the expression - if($upper[0] == '(') { - #$expression = substr($expression,1,-1); - $base_expression = $expression; - } - - $tokens = $this->split_sql($expression); - $token_count = count($tokens); - - /* Determine if there is an explicit alias after the AS clause. - * If AS is found, then the next non-whitespace token is captured as the alias. - * The tokens after (and including) the AS are removed. - */ - $base_expr = ""; - $stripped = array(); - $capture = false; - $alias = ""; - $processed = false; - for($i = 0;$i < $token_count;++$i) { - $token = strtoupper($tokens[$i]); - if(trim($token)) { - $stripped[] = $tokens[$i]; - } - - if($token == 'AS') { - unset($tokens[$i]); - $capture = true; - continue; - } - - if($capture) { - if(trim($token)) { - $alias .= $tokens[$i]; - } - unset($tokens[$i]); - continue; - } - $base_expr .= $tokens[$i]; - } - - $stripped = $this->process_expr_list($stripped); - $last = array_pop($stripped); - if(!$alias && $last['expr_type'] == 'colref') { - $prev = array_pop($stripped); - if($prev['expr_type'] == 'operator' || - $prev['expr_type'] == 'const' || - $prev['expr_type'] == 'function' || - $prev['expr_type'] == 'expression' || - #$prev['expr_type'] == 'aggregate_function' || - $prev['expr_type'] == 'subquery' || - $prev['expr_type'] == 'colref') { - $alias = $last['base_expr']; - - #remove the last token - array_pop($tokens); - - $base_expr = join("", $tokens); - - } - } - - if(!$alias) { - $base_expr = join("", $tokens); - $alias = $base_expr; - } - - /* Properly escape the alias if it is not escaped */ - if ($alias[0] != '`') { - $alias = '`' . str_replace('`', '``', $alias) . '`'; - } - $processed = false; - $type = 'expression'; - - if(substr(trim($base_expr), 0, 1) == '(') { - //-- $base_expr = substr($expression,1,-1); - if(preg_match('/^sel/i', $base_expr)) { - $type = 'subquery'; - $processed = $this->parse($base_expr); - } - } - if(!$processed) { - $processed = $this->process_expr_list($tokens); - } - - if(count($processed) == 1) { - $type = $processed[0]['expr_type']; - $processed = false; - } - - return array('expr_type' => $type, 'alias' => $alias, 'base_expr' => $base_expr, 'sub_tree' => $processed); - - } - - - private function process_from(&$tokens) - { - $expression = ""; - $expr = array(); - $token_count = 0; - $table = ""; - $alias = ""; - - $skip_next = false; - $i = 0; - $join_type = ''; - $ref_type = ""; - $ref_expr = ""; - $base_expr = ""; - $sub_tree = false; - $subquery = ""; - - $first_join = true; - $modifier = ""; - $saved_join_type = ""; - - foreach($tokens as $token) { - $base_expr = false; - $upper = strtoupper(trim($token)); - - if($skip_next && $token) { - $token_count++; - $skip_next = false; - continue; - } else { - if($skip_next) { - continue; - } - } - - if(preg_match("/^\\s*\\(\\s*select/i", $token)) { - $type = 'subquery'; - $table = "DEPENDENT-SUBQUERY"; - $sub_tree = $this->parse(trim($token, '() ')); - $subquery = $token; - } - - switch($upper) { - case 'OUTER': - case 'LEFT': - case 'RIGHT': - case 'NATURAL': - case 'CROSS': - case ',': - case 'JOIN': - break; - - default: - $expression .= ($token == '') ? " " : $token; - if($ref_type) { - $ref_expr .= ($token == '') ? " " : $token; - } - break; - } - - switch($upper) { - case 'AS': - $token_count++; - $n = 1; - $alias = ""; - while($alias == "") { - $alias = trim($tokens[$i + $n]); - ++$n; - } - - continue; - break; - - case 'INDEX': - if($token_category == 'CREATE') { - $token_category = $upper; - continue 2; - } - - break; - - case 'USING': - case 'ON': - $ref_type = $upper; - $ref_expr = ""; - - case 'CROSS': - case 'USE': - case 'FORCE': - case 'IGNORE': - case 'INNER': - case 'OUTER': - # $expression .= $token; - $token_count++; - continue; - break; - - case 'FOR': - $token_count++; - $skip_next = true; - continue; - break; - - case 'LEFT': - case 'RIGHT': - case 'STRAIGHT_JOIN': - $join_type = $saved_join_type; - - $modifier = $upper . " "; - break; - - - case ',': - $modifier = 'CROSS'; - - case 'JOIN': - - if($first_join) { - $join_type = 'JOIN'; - $saved_join_type = ($modifier ? $modifier : 'JOIN'); - } else { - $new_join_type = ($modifier ? $modifier : 'JOIN'); - $join_type = $saved_join_type; - $saved_join_type = $new_join_type; - unset($new_join_type); - } - - $first_join = false; - - if(!trim($alias)) $alias = $table; - - - if($subquery) { - $sub_tree = $this->parse(trim($subquery, '()')); - $base_expr = $subquery; - } - - if(substr(trim($table), 0, 1) == '(') { - $base_expr = trim($table,'() '); - $join_type = 'JOIN'; - $sub_tree = $this->process_from($this->split_sql($base_expr)); - $alias = ""; - } - - - if($join_type == "") $join_type = 'JOIN'; - $expr[] = array('table' => $table, 'alias' => $alias, 'join_type' => $join_type, 'ref_type' => $ref_type, 'ref_clause' => trim($ref_expr,'() '), 'base_expr' => $base_expr, 'sub_tree' => $sub_tree); - $modifier = ""; - #$join_type=$saved_join_type; - - - $token_count = 0; - $table = $alias = $expression = $base_expr = $ref_type = $ref_expr = ""; - $sub_tree = false; - $subquery = ""; - - break; - - - default: - if($token === false || empty($token) || $token === "") continue; - - if($token_count == 0 ) { - if(!$table) { - $table = $token ; - } - } else if($token_count == 1) { - $alias = $token; - } - $token_count++; - break; - } - ++$i; - } - if(substr(trim($table), 0, 1) == '(') { - $base_expr = trim($table, '() '); - $join_type = 'JOIN'; - $sub_tree = $this->process_from($this->split_sql($base_expr)); - $alias = ""; - } else { - if(!trim($alias)) $alias = $table; - } - if($join_type == "") $saved_join_type = 'JOIN'; - - $expr[] = array('table' => $table, 'alias' => $alias,'join_type' => $saved_join_type, 'ref_type' => $ref_type, 'ref_clause' => trim($ref_expr, '() '), 'base_expr' => $base_expr, 'sub_tree' => $sub_tree); - - return $expr; - } - - private function process_group(&$tokens, &$select) - { - - $out = array(); - $expression = ""; - $direction = "ASC"; - $type = "expression"; - if(!$tokens) return false; - - foreach($tokens as $token) { - switch(strtoupper($token)) { - case ',': - $expression = trim($expression); - if($expression[0] != '`' || substr($expression,-1) != '`') { - $escaped = str_replace('`', '``', $expression); - } else { - $escaped = $expression; - } - $escaped = '`' . $escaped . '`'; - - if(is_numeric(trim($expression))) { - $type = 'pos'; - } else { - - #search to see if the expression matches an alias - foreach($select as $clause) { - if($clause['alias'] == $escaped) { - $type = 'alias'; - } + if (empty( $tokens[$i] )) { + continue; } - if(!$type) $type = "expression"; - } - - $out[] = array('type' => $type, 'base_expr' => $expression, 'direction' => $direction); - $escaped = ""; - $expression = ""; - $direction = "ASC"; - $type = ""; - break; - - case 'DESC': - $direction = "DESC"; - break; - - default: - $expression .= $token == '' ? ' ' : $token; - - - } - } - if($expression) { - $expression = trim($expression); - if($expression[0] != '`' || substr($expression,-1) != '`') { - $escaped = str_replace('`', '``', $expression); - } else { - $escaped = $expression; - } - $escaped = '`' . $escaped . '`'; - - if(is_numeric(trim($expression))) { - $type = 'pos'; - } else { - - #search to see if the expression matches an alias - if(!$type && $select) { - foreach($select as $clause) { - if(!is_array($clause)) continue; - if($clause['alias'] == $escaped) { - $type = 'alias'; - } - } - } else { - $type = "expression"; - } - - if(!$type) $type = "expression"; - } - - $out[] = array('type' => $type, 'base_expr' => $expression, 'direction' => $direction); - } - - return $out; - } - - /** - * Some sections are just lists of expressions, like the WHERE and HAVING clauses. This function - * processes these sections. Recursive. - */ - private function process_expr_list($tokens) - { - $expr = ""; - $type = ""; - $prev_token = ""; - $skip_next = false; - $sub_expr = ""; - - $in_lists = array(); - foreach($tokens as $key => $token) { - - if(strlen(trim($token)) == 0) continue; - if($skip_next) { - $skip_next = false; - continue; - } - - $processed = false; - $upper = strtoupper(trim($token)); - if(trim($token)) $token = trim($token); - - /* is it a subquery?*/ - if(preg_match("/^\\s*\\(\\s*SELECT/i", $token)) { - $type = 'subquery'; - #tokenize and parse the subquery. - #we remove the enclosing parenthesis for the tokenizer - $processed = $this->parse(trim($token, ' ()')); - - - /* is it an inlist */ - } elseif( $upper[0] == '(' && substr($upper, -1) == ')' ) { - if($prev_token == 'IN') { - $type = "in-list"; - $processed = $this->split_sql(substr($token, 1, -1)); - $list = array(); - foreach($processed as $v) { - if($v == ',') continue; - $list[] = $v; - } - $processed = $list; - unset($list); - $prev_token = ""; - - } - elseif($prev_token == 'AGAINST') { - $type = "match-arguments"; - $list = $this->split_sql(substr($token, 1, -1)); - if(count($list) > 1){ - $match_mode = implode('', array_slice($list, 1)); - $processed = array($list[0], $match_mode); - } - else - $processed = $list[0]; - $prev_token = ""; - } - - /* it is either an operator, a colref or a constant */ - } else { - switch($upper) { - case 'AND': - case '&&': - case 'BETWEEN': - case 'AND': - case 'BINARY': - case '&': - case '~': - case '|': - case '^': - case 'CASE': - case 'WHEN': - case 'END': - case 'DIV': - case '/': - case '<=>': - case '=': - case '>=': - case '>': - case 'IS': - case 'NOT': - case 'NULL': - case '<<': - case '<=': - case '<': - case 'LIKE': - case '-': - case '%': - case '!=': - case '<>': - case 'REGEXP': - case '!': - case '||': - case 'OR': - case '+': - case '>>': - case 'RLIKE': - case 'SOUNDS': - case '*': - case '-': - case 'XOR': - case 'IN': - $processed = false; - $type = "operator"; - break; - default: - switch($token[0]) { - case "'": - case '"': - $type = 'const'; - break; - case '`': - $type = 'colref'; - break; - - default: - if(is_numeric($token)) { - $type = 'const'; - } else { - $type = 'colref'; + $token = $tokens[$i]; + $trim = trim( $token ); + if ($trim) { + if ($trim[0] != '(' && substr( $trim, - 1 ) == ')') { + $trim = trim( substr( $trim, 0, strpos( $trim, '(' ) ) ); } - break; + $tokens[$i] = $trim; + $token = $trim; + } + + if ($token && $token[0] == '(') { + $info = $this->count_paren( $token ); + if ($info['balanced'] == 0) { + continue; + } + + #we need to find this many closing parens + $needed = abs( $info['balanced'] ); + $n = $i; + while ($needed > 0 && $n < $token_count - 1) { + ++ $n; + #echo "LOOKING FORWARD TO $n [ " . $tokens[$n] . "]\n"; + $token2 = $tokens[$n]; + $info2 = $this->count_paren( $token2 ); + $closes = count( $info2['close'] ); + if ($closes != $needed) { + $tokens[$i] .= $tokens[$n]; + unset( $tokens[$n] ); + $reset = true; + $info2 = $this->count_paren( $tokens[$i] ); + $needed = abs( $info2['balanced'] ); + # echo "CLOSES LESS THAN NEEDED (still need $needed)\n"; + } else { + /*get the string pos of the last close paren we need*/ + $pos = $info2['close'][count( $info2['close'] ) - 1]; + $str1 = $str2 = ""; + if ($pos == 0) { + $str1 = ')'; + } else { + $str1 = substr( $tokens[$n], 0, $pos ) . ')'; + $str2 = substr( $tokens[$n], $pos + 1 ); + } + #echo "CLOSES FOUND AT $n, offset:$pos [$str1] [$str2]\n"; + if (strlen( $str2 ) > 0) { + $tokens[$n] = $str2; + } else { + unset( $tokens[$n] ); + $reset = true; + } + $tokens[$i] .= $str1; + $info2 = $this->count_paren( $tokens[$i] ); + $needed = abs( $info2['balanced'] ); + + } + } + } + } + + #the same problem appears with backticks :( + + /* reset the array if we deleted any tokens above */ + if ($reset) { + $tokens = array_values( $tokens ); + } + + $token_count = count( $tokens ); + for ($i = 0; $i < $token_count; ++ $i) { + if (empty( $tokens[$i] )) { + continue; + } + $token = $tokens[$i]; + $needed = true; + $reset = false; + if ($needed && $token && strpos( $token, '`' ) !== false) { + $info = $this->count_backtick( $token ); + if ($info % 2 == 0) { + #even number of backticks means we are balanced + continue; + } + $needed = 1; + + $n = $i; + while ($needed && $n < $token_count - 1) { + $reset = true; + #echo "BACKTICK COUNT[$i]: $info old: {$tokens[$i]}, new: ($token)\n"; + ++ $n; + $token .= $tokens[$n]; + unset( $tokens[$n] ); + $needed = $this->count_backtick( $token ) % 2; + } + } + if ($reset) { + $tokens[$i] = $token; + } + + } + /* reset the array if we deleted any tokens above */ + $tokens = array_values( $tokens ); + + return $tokens; + + } + + /** + * This function breaks up the SQL statement into logical sections. + * Some sections are then further handled by specialized functions. + */ + private function process_sql (&$tokens, $start_at = 0, $stop_at = false) + { + $prev_category = ""; + $start = microtime( true ); + $token_category = ""; + + $skip_next = false; + $token_count = count( $tokens ); + + if (! $stop_at) { + $stop_at = $token_count; + } + + $out = false; + + for ($token_number = $start_at; $token_number < $stop_at; ++ $token_number) { + $token = trim( $tokens[$token_number] ); + if ($token && $token[0] == '(' && $token_category == "") { + $token_category = 'SELECT'; + } + + /* If it isn't obvious, when $skip_next is set, then we ignore the next real + token, that is we ignore whitespace. + */ + if ($skip_next) { + #whitespace does not count as a next token + if ($token == "") { + continue; + } + + #to skip the token we replace it with whitespace + $new_token = ""; + $skip_next = false; + } + + $upper = strtoupper( $token ); + switch ($upper) { + + /* Tokens that get their own sections. These keywords have subclauses. */ + case 'SELECT': + case 'ORDER': + case 'LIMIT': + case 'SET': + case 'DUPLICATE': + case 'VALUES': + case 'GROUP': + case 'ORDER': + case 'HAVING': + case 'INTO': + case 'WHERE': + case 'RENAME': + case 'CALL': + case 'PROCEDURE': + case 'FUNCTION': + case 'DATABASE': + case 'SERVER': + case 'LOGFILE': + case 'DEFINER': + case 'RETURNS': + case 'EVENT': + case 'TABLESPACE': + case 'VIEW': + case 'TRIGGER': + case 'DATA': + case 'DO': + case 'PASSWORD': + case 'USER': + case 'PLUGIN': + case 'FROM': + case 'FLUSH': + case 'KILL': + case 'RESET': + case 'START': + case 'STOP': + case 'PURGE': + case 'EXECUTE': + case 'PREPARE': + case 'DEALLOCATE': + if ($token == 'DEALLOCATE') { + $skip_next = true; + } + /* this FROM is different from FROM in other DML (not join related) */ + if ($token_category == 'PREPARE' && $upper == 'FROM') { + continue 2; + } + + $token_category = $upper; + #$join_type = 'JOIN'; + if ($upper == 'FROM' && $token_category == 'FROM') { + /* DO NOTHING*/ + } else { + continue 2; + + } + break; + /* These tokens get their own section, but have no subclauses. + These tokens identify the statement but have no specific subclauses of their own. */ + case 'DELETE': + case 'ALTER': + case 'INSERT': + case 'REPLACE': + case 'TRUNCATE': + case 'CREATE': + case 'TRUNCATE': + case 'OPTIMIZE': + case 'GRANT': + case 'REVOKE': + case 'SHOW': + case 'HANDLER': + case 'LOAD': + case 'ROLLBACK': + case 'SAVEPOINT': + case 'UNLOCK': + case 'INSTALL': + case 'UNINSTALL': + case 'ANALZYE': + case 'BACKUP': + case 'CHECK': + case 'CHECKSUM': + case 'REPAIR': + case 'RESTORE': + case 'CACHE': + case 'DESCRIBE': + case 'EXPLAIN': + case 'USE': + case 'HELP': + $token_category = $upper; /* set the category in case these get subclauses in a future version of MySQL */ + $out[$upper][0] = $upper; + continue 2; + break; + /* This is either LOCK TABLES or SELECT ... LOCK IN SHARE MODE*/ + case 'LOCK': + if ($token_category == "") { + $token_category = $upper; + $out[$upper][0] = $upper; + } else { + $token = 'LOCK IN SHARE MODE'; + $skip_next = true; + $out['OPTIONS'][] = $token; + } + continue 2; + break; + case 'USING': + /* USING in FROM clause is different from USING w/ prepared statement*/ + if ($token_category == 'EXECUTE') { + $token_category = $upper; + continue 2; + } + if ($token_category == 'FROM' && ! empty( $out['DELETE'] )) { + $token_category = $upper; + continue 2; + } + break; + /* DROP TABLE is different from ALTER TABLE DROP ... */ + case 'DROP': + if ($token_category != 'ALTER') { + $token_category = $upper; + $out[$upper][0] = $upper; + continue 2; + } + break; + case 'FOR': + $skip_next = true; + $out['OPTIONS'][] = 'FOR UPDATE'; + continue 2; + break; + case 'UPDATE': + if ($token_category == "") { + $token_category = $upper; + continue 2; + + } + if ($token_category == 'DUPLICATE') { + continue 2; + } + break; + break; + case 'START': + $token = "BEGIN"; + $out[$upper][0] = $upper; + $skip_next = true; + break; + /* These tokens are ignored. */ + case 'BY': + case 'ALL': + case 'SHARE': + case 'MODE': + case 'TO': + case ';': + continue 2; + break; + case 'KEY': + if ($token_category == 'DUPLICATE') { + continue 2; + } + break; + /* These tokens set particular options for the statement. They never stand alone.*/ + case 'DISTINCTROW': + $token = 'DISTINCT'; + //DISTINCTROW seemed deprecated + case 'DISTINCT': + case 'HIGH_PRIORITY': + case 'LOW_PRIORITY': + case 'DELAYED': + case 'IGNORE': + case 'FORCE': + case 'STRAIGHT_JOIN': + case 'SQL_SMALL_RESULT': + case 'SQL_BIG_RESULT': + case 'QUICK': + case 'SQL_BUFFER_RESULT': + case 'SQL_CACHE': + case 'SQL_NO_CACHE': + case 'SQL_CALC_FOUND_ROWS': + $out['OPTIONS'][] = $upper; + continue 2; + break; + case 'WITH': + if ($token_category == 'GROUP') { + $skip_next = true; + $out['OPTIONS'][] = 'WITH ROLLUP'; + continue 2; + } + break; + case 'AS': + break; + case '': + case ',': + case ';': + break; + default: + break; + } + + if ($prev_category == $token_category) { + $out[$token_category][] = $token; + } + + $prev_category = $token_category; + } + + if (! $out) { + return false; + } + + #process the SELECT clause + if (! empty( $out['SELECT'] )) { + $out['SELECT'] = $this->process_select( $out['SELECT'] ); + } + if (! empty( $out['FROM'] )) { + $out['FROM'] = $this->process_from( $out['FROM'] ); + } + if (! empty( $out['USING'] )) { + $out['USING'] = $this->process_from( $out['USING'] ); + } + if (! empty( $out['UPDATE'] )) { + $out['UPDATE'] = $this->process_from( $out['UPDATE'] ); + } + if (! empty( $out['GROUP'] )) { + $out['GROUP'] = $this->process_group( $out['GROUP'], $out['SELECT'] ); + } + if (! empty( $out['ORDER'] )) { + $out['ORDER'] = $this->process_group( $out['ORDER'], $out['SELECT'] ); + } + if (! empty( $out['LIMIT'] )) { + $out['LIMIT'] = $this->process_limit( $out['LIMIT'] ); + } + if (! empty( $out['WHERE'] )) { + $out['WHERE'] = $this->process_expr_list( $out['WHERE'] ); + } + if (! empty( $out['HAVING'] )) { + $out['HAVING'] = $this->process_expr_list( $out['HAVING'] ); + } + if (! empty( $out['SET'] )) { + $out['SET'] = $this->process_set_list( $out['SET'] ); + } + if (! empty( $out['DUPLICATE'] )) { + $out['ON DUPLICATE KEY UPDATE'] = $this->process_set_list( $out['DUPLICATE'] ); + unset( $out['DUPLICATE'] ); + } + if (! empty( $out['INSERT'] )) { + $out = $this->process_insert( $out ); + } + if (! empty( $out['REPLACE'] )) { + $out = $this->process_insert( $out, 'REPLACE' ); + } + if (! empty( $out['DELETE'] )) { + $out = $this->process_delete( $out ); + } + + return $out; + + } + + /** + * A SET list is simply a list of key = value expressions separated by comma (,). + * This function produces a list of the key/value expressions. + */ + private function process_set_list ($tokens) + { + $column = ""; + $expression = ""; + foreach ($tokens as $token) { + $token = trim( $token ); + if (! $column) { + if ($token === false || empty( $token )) { + continue; + } + $column .= $token; + continue; + } + + if ($token == '=') { + continue; + } + + if ($token == ',') { + $expr[] = array ('column' => trim( $column ),'expr' => trim( $expression ) + ); + $expression = $column = ""; + continue; + } + + $expression .= $token; + } + if ($expression) { + $expr[] = array ('column' => trim( $column ),'expr' => trim( $expression ) + ); + } + + return $expr; + } + + /** + * This function processes the LIMIT section. + * start,end are set. If only end is provided in the query + * then start is set to 0. + */ + private function process_limit ($tokens) + { + $start = 0; + $end = 0; + + if ($pos = array_search( ',', $tokens )) { + for ($i = 0; $i < $pos; ++ $i) { + if ($tokens[$i] != '') { + $start = $tokens[$i]; + break; + } + } + $pos = $pos + 1; + + } else { + $pos = 0; + } + + for ($i = $pos; $i < count( $tokens ); ++ $i) { + if ($tokens[$i] != '') { + $end = $tokens[$i]; + break; + } + } + + return array ('start' => $start,'end' => $end + ); + } + + /* This function processes the SELECT section. It splits the clauses at the commas. + * Each clause is then processed by process_select_expr() and the results are added to + * the expression list. + * + * Finally, at the end, the epxression list is returned. + */ + private function process_select (&$tokens) + { + $expression = ""; + $expr = array (); + foreach ($tokens as $token) { + if ($token == ',') { + $expr[] = $this->process_select_expr( trim( $expression ) ); + $expression = ""; + } else { + if ($token === "" || $token === false) { + $token = " "; + } + $expression .= $token; + } + } + if ($expression) { + $expr[] = $this->process_select_expr( trim( $expression ) ); + } + return $expr; + } + + /** + * This fuction processes each SELECT clause. + * We determine what (if any) alias + * is provided, and we set the type of expression. + */ + private function process_select_expr ($expression) + { + $capture = false; + $alias = ""; + $base_expression = $expression; + $upper = trim( strtoupper( $expression ) ); + #if necessary, unpack the expression + if ($upper[0] == '(') { + #$expression = substr($expression,1,-1); + $base_expression = $expression; + } + + $tokens = $this->split_sql( $expression ); + $token_count = count( $tokens ); + + /* Determine if there is an explicit alias after the AS clause. + * If AS is found, then the next non-whitespace token is captured as the alias. + * The tokens after (and including) the AS are removed. + */ + $base_expr = ""; + $stripped = array (); + $capture = false; + $alias = ""; + $processed = false; + for ($i = 0; $i < $token_count; ++ $i) { + $token = strtoupper( $tokens[$i] ); + if (trim( $token )) { + $stripped[] = $tokens[$i]; + } + + if ($token == 'AS') { + unset( $tokens[$i] ); + $capture = true; + continue; + } + + if ($capture) { + if (trim( $token )) { + $alias .= $tokens[$i]; + } + unset( $tokens[$i] ); + continue; + } + $base_expr .= $tokens[$i]; + } + + $stripped = $this->process_expr_list( $stripped ); + $last = array_pop( $stripped ); + if (! $alias && $last['expr_type'] == 'colref') { + $prev = array_pop( $stripped ); + if ($prev['expr_type'] == 'operator' || $prev['expr_type'] == 'const' || $prev['expr_type'] == 'function' || $prev['expr_type'] == 'expression' || + #$prev['expr_type'] == 'aggregate_function' || + $prev['expr_type'] == 'subquery' || $prev['expr_type'] == 'colref') { + $alias = $last['base_expr']; + + #remove the last token + array_pop( $tokens ); + + $base_expr = join( "", $tokens ); } - #$processed = $token; - $processed = false; } - } - /* is a reserved word? */ - if(($type != 'operator' && $type != 'in-list' && $type != 'sub_expr') && in_array($upper, $this->reserved)) { - $token = $upper; - if(!in_array($upper,$this->functions)) { - $type = 'reserved'; + + if (! $alias) { + $base_expr = join( "", $tokens ); + $alias = $base_expr; + } + + /* Properly escape the alias if it is not escaped */ + if ($alias[0] != '`') { + $alias = '`' . str_replace( '`', '``', $alias ) . '`'; + } + $processed = false; + $type = 'expression'; + + if (substr( trim( $base_expr ), 0, 1 ) == '(') { + //-- $base_expr = substr($expression,1,-1); + if (preg_match( '/^sel/i', $base_expr )) { + $type = 'subquery'; + $processed = $this->parse( $base_expr ); + } + } + if (! $processed) { + $processed = $this->process_expr_list( $tokens ); + } + + if (count( $processed ) == 1) { + $type = $processed[0]['expr_type']; + $processed = false; + } + + return array ('expr_type' => $type,'alias' => $alias,'base_expr' => $base_expr,'sub_tree' => $processed + ); + + } + + private function process_from (&$tokens) + { + $expression = ""; + $expr = array (); + $token_count = 0; + $table = ""; + $alias = ""; + + $skip_next = false; + $i = 0; + $join_type = ''; + $ref_type = ""; + $ref_expr = ""; + $base_expr = ""; + $sub_tree = false; + $subquery = ""; + + $first_join = true; + $modifier = ""; + $saved_join_type = ""; + + foreach ($tokens as $token) { + $base_expr = false; + $upper = strtoupper( trim( $token ) ); + + if ($skip_next && $token) { + $token_count ++; + $skip_next = false; + continue; + } else { + if ($skip_next) { + continue; + } + } + + if (preg_match( "/^\\s*\\(\\s*select/i", $token )) { + $type = 'subquery'; + $table = "DEPENDENT-SUBQUERY"; + $sub_tree = $this->parse( trim( $token, '() ' ) ); + $subquery = $token; + } + + switch ($upper) { + case 'OUTER': + case 'LEFT': + case 'RIGHT': + case 'NATURAL': + case 'CROSS': + case ',': + case 'JOIN': + break; + default: + $expression .= ($token == '') ? " " : $token; + if ($ref_type) { + $ref_expr .= ($token == '') ? " " : $token; + } + break; + } + switch ($upper) { + case 'AS': + $token_count ++; + $n = 1; + $alias = ""; + while ($alias == "") { + $alias = trim( $tokens[$i + $n] ); + ++ $n; + } + + continue; + break; + case 'INDEX': + if ($token_category == 'CREATE') { + $token_category = $upper; + continue 2; + } + + break; + case 'USING': + case 'ON': + $ref_type = $upper; + $ref_expr = ""; + //ON is ... + case 'CROSS': + case 'USE': + case 'FORCE': + case 'IGNORE': + case 'INNER': + case 'OUTER': + # $expression .= $token; + $token_count ++; + continue; + break; + case 'FOR': + $token_count ++; + $skip_next = true; + continue; + break; + case 'LEFT': + case 'RIGHT': + case 'STRAIGHT_JOIN': + $join_type = $saved_join_type; + $modifier = $upper . " "; + break; + case ',': + $modifier = 'CROSS'; + // ',' got the same process as JOIN + case 'JOIN': + + if ($first_join) { + $join_type = 'JOIN'; + $saved_join_type = ($modifier ? $modifier : 'JOIN'); + } else { + $new_join_type = ($modifier ? $modifier : 'JOIN'); + $join_type = $saved_join_type; + $saved_join_type = $new_join_type; + unset( $new_join_type ); + } + + $first_join = false; + + if (! trim( $alias )) { + $alias = $table; + } + + if ($subquery) { + $sub_tree = $this->parse( trim( $subquery, '()' ) ); + $base_expr = $subquery; + } + + if (substr( trim( $table ), 0, 1 ) == '(') { + $base_expr = trim( $table, '() ' ); + $join_type = 'JOIN'; + $sub_tree = $this->process_from( $this->split_sql( $base_expr ) ); + $alias = ""; + } + + if ($join_type == "") { + $join_type = 'JOIN'; + } + $expr[] = array ('table' => $table,'alias' => $alias,'join_type' => $join_type,'ref_type' => $ref_type,'ref_clause' => trim( $ref_expr, '() ' ),'base_expr' => $base_expr,'sub_tree' => $sub_tree + ); + $modifier = ""; + #$join_type=$saved_join_type; + + $token_count = 0; + $table = $alias = $expression = $base_expr = $ref_type = $ref_expr = ""; + $sub_tree = false; + $subquery = ""; + break; + default: + if ($token === false || empty( $token ) || $token === "") { + continue; + } + + if ($token_count == 0) { + if (! $table) { + $table = $token; + } + } elseif ($token_count == 1) { + $alias = $token; + } + $token_count ++; + break; + } + ++ $i; + } + if (substr( trim( $table ), 0, 1 ) == '(') { + $base_expr = trim( $table, '() ' ); + $join_type = 'JOIN'; + $sub_tree = $this->process_from( $this->split_sql( $base_expr ) ); + $alias = ""; } else { - switch($token) { - case 'AVG': - case 'SUM': - case 'COUNT': - case 'MIN': - case 'MAX': - case 'STDDEV': - case 'STDDEV_SAMP': - case 'STDDEV_POP': - case 'VARIANCE': - case 'VAR_SAMP': - case 'VAR_POP': - case 'GROUP_CONCAT': - case 'BIT_AND': - case 'BIT_OR': - case 'BIT_XOR': - $type = 'aggregate_function'; - if(!empty($tokens[$key + 1])) $sub_expr = $tokens[$key + 1]; - #$skip_next=true; - break; - - default: - $type = 'function'; - if(!empty($tokens[$key + 1])) $sub_expr = $tokens[$key + 1]; else $sub_expr = "()"; - #$skip_next=true; - - break; - } + if (! trim( $alias )) { + $alias = $table; + } + } + if ($join_type == "") { + $saved_join_type = 'JOIN'; } - } - if(!$type) { - if($upper[0] == '(') { - $local_expr = substr(trim($token), 1, -1); + $expr[] = array ('table' => $table,'alias' => $alias,'join_type' => $saved_join_type,'ref_type' => $ref_type,'ref_clause' => trim( $ref_expr, '() ' ),'base_expr' => $base_expr,'sub_tree' => $sub_tree + ); + + return $expr; + } + + private function process_group (&$tokens, &$select) + { + + $out = array (); + $expression = ""; + $direction = "ASC"; + $type = "expression"; + if (! $tokens) { + return false; + } + + foreach ($tokens as $token) { + switch (strtoupper( $token )) { + case ',': + $expression = trim( $expression ); + if ($expression[0] != '`' || substr( $expression, - 1 ) != '`') { + $escaped = str_replace( '`', '``', $expression ); + } else { + $escaped = $expression; + } + $escaped = '`' . $escaped . '`'; + + if (is_numeric( trim( $expression ) )) { + $type = 'pos'; + } else { + + #search to see if the expression matches an alias + foreach ($select as $clause) { + if ($clause['alias'] == $escaped) { + $type = 'alias'; + } + } + + if (! $type) { + $type = "expression"; + } + } + + $out[] = array ('type' => $type,'base_expr' => $expression,'direction' => $direction + ); + $escaped = ""; + $expression = ""; + $direction = "ASC"; + $type = ""; + break; + case 'DESC': + $direction = "DESC"; + break; + default: + $expression .= $token == '' ? ' ' : $token; + + } + } + if ($expression) { + $expression = trim( $expression ); + if ($expression[0] != '`' || substr( $expression, - 1 ) != '`') { + $escaped = str_replace( '`', '``', $expression ); + } else { + $escaped = $expression; + } + $escaped = '`' . $escaped . '`'; + + if (is_numeric( trim( $expression ) )) { + $type = 'pos'; + } else { + + #search to see if the expression matches an alias + if (! $type && $select) { + foreach ($select as $clause) { + if (! is_array( $clause )) { + continue; + } + if ($clause['alias'] == $escaped) { + $type = 'alias'; + } + } + } else { + $type = "expression"; + } + + if (! $type) { + $type = "expression"; + } + } + + $out[] = array ('type' => $type,'base_expr' => $expression,'direction' => $direction + ); + } + + return $out; + } + + /** + * Some sections are just lists of expressions, like the WHERE and HAVING clauses. + * This function + * processes these sections. Recursive. + */ + private function process_expr_list ($tokens) + { + $expr = ""; + $type = ""; + $prev_token = ""; + $skip_next = false; + $sub_expr = ""; + + $in_lists = array (); + foreach ($tokens as $key => $token) { + + if (strlen( trim( $token ) ) == 0) { + continue; + } + if ($skip_next) { + $skip_next = false; + continue; + } + + $processed = false; + $upper = strtoupper( trim( $token ) ); + if (trim( $token )) { + $token = trim( $token ); + } + + /* is it a subquery?*/ + if (preg_match( "/^\\s*\\(\\s*SELECT/i", $token )) { + $type = 'subquery'; + #tokenize and parse the subquery. + #we remove the enclosing parenthesis for the tokenizer + $processed = $this->parse( trim( $token, ' ()' ) ); + + /* is it an inlist */ + } elseif ($upper[0] == '(' && substr( $upper, - 1 ) == ')') { + if ($prev_token == 'IN') { + $type = "in-list"; + $processed = $this->split_sql( substr( $token, 1, - 1 ) ); + $list = array (); + foreach ($processed as $v) { + if ($v == ',') { + continue; + } + $list[] = $v; + } + $processed = $list; + unset( $list ); + $prev_token = ""; + + } elseif ($prev_token == 'AGAINST') { + $type = "match-arguments"; + $list = $this->split_sql( substr( $token, 1, - 1 ) ); + if (count( $list ) > 1) { + $match_mode = implode( '', array_slice( $list, 1 ) ); + $processed = array ($list[0],$match_mode + ); + } else { + $processed = $list[0]; + } + $prev_token = ""; + } + + /* it is either an operator, a colref or a constant */ + } else { + switch ($upper) { + case 'AND': + case '&&': + case 'BETWEEN': + case 'AND': + case 'BINARY': + case '&': + case '~': + case '|': + case '^': + case 'CASE': + case 'WHEN': + case 'END': + case 'DIV': + case '/': + case '<=>': + case '=': + case '>=': + case '>': + case 'IS': + case 'NOT': + case 'NULL': + case '<<': + case '<=': + case '<': + case 'LIKE': + case '-': + case '%': + case '!=': + case '<>': + case 'REGEXP': + case '!': + case '||': + case 'OR': + case '+': + case '>>': + case 'RLIKE': + case 'SOUNDS': + case '*': + case '-': + case 'XOR': + case 'IN': + $processed = false; + $type = "operator"; + break; + default: + switch ($token[0]) { + case "'": + case '"': + $type = 'const'; + break; + case '`': + $type = 'colref'; + break; + default: + if (is_numeric( $token )) { + $type = 'const'; + } else { + $type = 'colref'; + } + break; + + } + #$processed = $token; + $processed = false; + } + } + /* is a reserved word? */ + if (($type != 'operator' && $type != 'in-list' && $type != 'sub_expr') && in_array( $upper, $this->reserved )) { + $token = $upper; + if (! in_array( $upper, $this->functions )) { + $type = 'reserved'; + } else { + switch ($token) { + case 'AVG': + case 'SUM': + case 'COUNT': + case 'MIN': + case 'MAX': + case 'STDDEV': + case 'STDDEV_SAMP': + case 'STDDEV_POP': + case 'VARIANCE': + case 'VAR_SAMP': + case 'VAR_POP': + case 'GROUP_CONCAT': + case 'BIT_AND': + case 'BIT_OR': + case 'BIT_XOR': + $type = 'aggregate_function'; + if (! empty( $tokens[$key + 1] )) { + $sub_expr = $tokens[$key + 1]; + #$skip_next=true; + } + break; + default: + $type = 'function'; + if (! empty( $tokens[$key + 1] )) { + $sub_expr = $tokens[$key + 1]; + } else { + $sub_expr = "()"; + #$skip_next=true; + } + break; + } + } + } + + if (! $type) { + if ($upper[0] == '(') { + $local_expr = substr( trim( $token ), 1, - 1 ); + } else { + $local_expr = $token; + } + $processed = $this->process_expr_list( $this->split_sql( $local_expr ) ); + $type = 'expression'; + + if (count( $processed ) == 1) { + $type = $processed[0]['expr_type']; + $base_expr = $processed[0]['base_expr']; + $processed = $processed[0]['sub_tree']; + } + + } + + $sub_expr = trim( $sub_expr ); + $sub_expr = ""; + + $expr[] = array ('expr_type' => $type,'base_expr' => $token,'sub_tree' => $processed + ); + $prev_token = $upper; + $expr_type = ""; + $type = ""; + } + if ($sub_expr) { + $processed['sub_tree'] = $this->process_expr_list( $this->split_sql( substr( $sub_expr, 1, - 1 ) ) ); + } + + if (! is_array( $processed )) { + print_r( $processed ); + $processed = false; + } + + if ($expr_type) { + $expr[] = array ('expr_type' => $type,'base_expr' => $token,'sub_tree' => $processed + ); + } + $mod = false; + + if ($mod) { + $expr = array_values( $expr ); + } + + return $expr; + } + + private function process_update ($tokens) + { + + } + + private function process_delete ($tokens) + { + $tables = array (); + $del = $tokens['DELETE']; + + foreach ($tokens['DELETE'] as $expression) { + if ($expression != 'DELETE' && trim( $expression, ' .*' ) != "" && $expression != ',') { + $tables[] = trim( $expression, '.* ' ); + } + } + + if (empty( $tables )) { + foreach ($tokens['FROM'] as $table) { + $tables[] = $table['table']; + } + } + + $tokens['DELETE'] = array ('TABLES' => $tables + ); + + return $tokens; + } + + public function process_insert ($tokens, $token_category = 'INSERT') + { + $table = ""; + $cols = ""; + + $into = $tokens['INTO']; + foreach ($into as $token) { + if (! trim( $token )) { + continue; + } + if (! $table) { + $table = $token; + } elseif (! $cols) { + $cols = $token; + } + } + + if (! $cols) { + $cols = 'ALL'; } else { - $local_expr = $token; + $cols = explode( ",", trim( $cols, '() ' ) ); } - $processed = $this->process_expr_list($this->split_sql($local_expr)); - $type = 'expression'; + unset( $tokens['INTO'] ); + $tokens[$token_category] = array ('table' => $table,'cols' => $cols + ); + return $tokens; - if(count($processed) == 1) { - $type = $processed[0]['expr_type']; - $base_expr = $processed[0]['base_expr']; - $processed = $processed[0]['sub_tree']; - } - - } - - $sub_expr = trim($sub_expr); - $sub_expr = ""; - - $expr[] = array( 'expr_type' => $type, 'base_expr' => $token, 'sub_tree' => $processed); - $prev_token = $upper; - $expr_type = ""; - $type = ""; - } - if($sub_expr) { - $processed['sub_tree'] = $this->process_expr_list($this->split_sql(substr($sub_expr, 1, -1))); } - if(!is_array($processed)) { + public function load_reserved_words () + { - print_r($processed); - $processed = false; + $this->functions = array ('abs','acos','adddate','addtime','aes_encrypt','aes_decrypt','against','ascii','asin','atan','avg','benchmark','bin','bit_and','bit_or','bitcount','bitlength','cast','ceiling','char','char_length','character_length','charset','coalesce','coercibility','collation','compress','concat','concat_ws','conection_id','conv','convert','convert_tz','cos','cot','count','crc32','curdate','current_user','currval','curtime','database','date_add','date_diff','date_format','date_sub','day','dayname','dayofmonth','dayofweek','dayofyear','decode','default','degrees','des_decrypt','des_encrypt','elt','encode','encrypt','exp','export_set','extract','field','find_in_set','floor','format','found_rows','from_days','from_unixtime','get_format','get_lock','group_concat', + 'greatest','hex','hour','if','ifnull','in','inet_aton','inet_ntoa','insert','instr','interval','is_free_lock','is_used_lock','last_day','last_insert_id','lcase','least','left','length','ln','load_file','localtime','localtimestamp','locate','log','log2','log10','lower','lpad','ltrim','make_set','makedate','maketime','master_pos_wait','match','max','md5','microsecond','mid','min','minute','mod','month','monthname','nextval','now','nullif','oct','octet_length','old_password','ord','password','period_add','period_diff','pi','position','pow','power','quarter','quote','radians','rand','release_lock','repeat','replace','reverse','right','round','row_count','rpad','rtrim','sec_to_time','second','session_user','sha','sha1','sign','soundex','space','sqrt','std','stddev', + 'stddev_pop','stddev_samp','strcmp','str_to_date','subdate','substring','substring_index','subtime','sum','sysdate','system_user','tan','time','timediff','timestamp','timestampadd','timestampdiff','time_format','time_to_sec','to_days','trim','truncate','ucase','uncompress','uncompressed_length','unhex','unix_timestamp','upper','user','utc_date','utc_time','utc_timestamp','uuid','var_pop','var_samp','variance','version','week','weekday','weekofyear','year','yearweek' + ); + + /* includes functions */ + $this->reserved = array ('abs','acos','adddate','addtime','aes_encrypt','aes_decrypt','against','ascii','asin','atan','avg','benchmark','bin','bit_and','bit_or','bitcount','bitlength','cast','ceiling','char','char_length','character_length','charset','coalesce','coercibility','collation','compress','concat','concat_ws','conection_id','conv','convert','convert_tz','cos','cot','count','crc32','curdate','current_user','currval','curtime','database','date_add','date_diff','date_format','date_sub','day','dayname','dayofmonth','dayofweek','dayofyear','decode','default','degrees','des_decrypt','des_encrypt','elt','encode','encrypt','exp','export_set','extract','field','find_in_set','floor','format','found_rows','from_days','from_unixtime','get_format','get_lock','group_concat','greatest', + 'hex','hour','if','ifnull','in','inet_aton','inet_ntoa','insert','instr','interval','is_free_lock','is_used_lock','last_day','last_insert_id','lcase','least','left','length','ln','load_file','localtime','localtimestamp','locate','log','log2','log10','lower','lpad','ltrim','make_set','makedate','maketime','master_pos_wait','match','max','md5','microsecond','mid','min','minute','mod','month','monthname','nextval','now','nullif','oct','octet_length','old_password','ord','password','period_add','period_diff','pi','position','pow','power','quarter','quote','radians','rand','release_lock','repeat','replace','reverse','right','round','row_count','rpad','rtrim','sec_to_time','second','session_user','sha','sha1','sign','soundex','space','sqrt','std','stddev','stddev_pop', + 'stddev_samp','strcmp','str_to_date','subdate','substring','substring_index','subtime','sum','sysdate','system_user','tan','time','timediff','timestamp','timestampadd','timestampdiff','time_format','time_to_sec','to_days','trim','truncate','ucase','uncompress','uncompressed_length','unhex','unix_timestamp','upper','user','utc_date','utc_time','utc_timestamp','uuid','var_pop','var_samp','variance','version','week','weekday','weekofyear','year','yearweek','add','all','alter','analyze','and','as','asc','asensitive','auto_increment','bdb','before','berkeleydb','between','bigint','binary','blob','both','by','call','cascade','case','change','char','character','check','collate','column','columns','condition','connection','constraint','continue','create','cross', + 'current_date','current_time','current_timestamp','cursor','database','databases','day_hour','day_microsecond','day_minute','day_second','dec','decimal','declare','default','delayed','delete','desc','describe','deterministic','distinct','distinctrow','div','double','drop','else','elseif','enclosed','escaped','exists','exit','explain','false','fetch','fields','float','for','force','foreign','found','frac_second','from','fulltext','grant','group','having','high_priority','hour_microsecond','hour_minute','hour_second','if','ignore','in','index','infile','inner','innodb','inout','insensitive','insert','int','integer','interval','into','io_thread','is','iterate','join','key','keys','kill','leading','leave','left','like','limit','lines','load','localtime','localtimestamp', + 'lock','long','longblob','longtext','loop','low_priority','master_server_id','match','mediumblob','mediumint','mediumtext','middleint','minute_microsecond','minute_second','mod','natural','not','no_write_to_binlog','null','numeric','on','optimize','option','optionally','or','order','out','outer','outfile','precision','primary','privileges','procedure','purge','read','real','references','regexp','rename','repeat','replace','require','restrict','return','revoke','right','rlike','second_microsecond','select','sensitive','separator','set','show','smallint','some','soname','spatial','specific','sql','sqlexception','sqlstate','sqlwarning','sql_big_result','sql_calc_found_rows','sql_small_result','sql_tsi_day','sql_tsi_frac_second','sql_tsi_hour','sql_tsi_minute', + 'sql_tsi_month','sql_tsi_quarter','sql_tsi_second','sql_tsi_week','sql_tsi_year','ssl','starting','straight_join','striped','table','tables','terminated','then','timestampadd','timestampdiff','tinyblob','tinyint','tinytext','to','trailing','true','undo','union','unique','unlock','unsigned','update','usage','use','user_resources','using','utc_date','utc_time','utc_timestamp','values','varbinary','varchar','varcharacter','varying','when','where','while','with','write','xor','year_month','zerofill' + ); + + for ($i = 0; $i < count( $this->reserved ); ++ $i) { + $this->reserved[$i] = strtoupper( $this->reserved[$i] ); + if (! empty( $this->functions[$i] )) { + $this->functions[$i] = strtoupper( $this->functions[$i] ); + } + } } +} - if($expr_type) { - $expr[] = array( 'expr_type' => $type, 'base_expr' => $token, 'sub_tree' => $processed); - } - $mod = false; - - if($mod) $expr = array_values($expr); - - return $expr; - } - - - - private function process_update($tokens) - { - - } - - private function process_delete($tokens) - { - $tables = array(); - $del = $tokens['DELETE']; - - foreach($tokens['DELETE'] as $expression) { - if ($expression != 'DELETE' && trim($expression,' .*') != "" && $expression != ',') { - $tables[] = trim($expression,'.* '); - } - } - - if(empty($tables)) { - foreach($tokens['FROM'] as $table) { - $tables[] = $table['table']; - } - } - - $tokens['DELETE'] = array('TABLES' => $tables); - - return $tokens; - } - - function process_insert($tokens, $token_category = 'INSERT') - { - $table = ""; - $cols = ""; - - $into = $tokens['INTO']; - foreach($into as $token) { - if(!trim($token)) continue; - if(!$table) { - $table = $token; - }elseif(!$cols) { - $cols = $token; - } - } - - if(!$cols) { - $cols = 'ALL'; - } else { - $cols = explode(",", trim($cols,'() ')); - } - unset($tokens['INTO']); - $tokens[$token_category] = array('table' => $table, 'cols' => $cols); - return $tokens; - - } - - - function load_reserved_words() - { - - $this->functions = array( - 'abs', - 'acos', - 'adddate', - 'addtime', - 'aes_encrypt', - 'aes_decrypt', - 'against', - 'ascii', - 'asin', - 'atan', - 'avg', - 'benchmark', - 'bin', - 'bit_and', - 'bit_or', - 'bitcount', - 'bitlength', - 'cast', - 'ceiling', - 'char', - 'char_length', - 'character_length', - 'charset', - 'coalesce', - 'coercibility', - 'collation', - 'compress', - 'concat', - 'concat_ws', - 'conection_id', - 'conv', - 'convert', - 'convert_tz', - 'cos', - 'cot', - 'count', - 'crc32', - 'curdate', - 'current_user', - 'currval', - 'curtime', - 'database', - 'date_add', - 'date_diff', - 'date_format', - 'date_sub', - 'day', - 'dayname', - 'dayofmonth', - 'dayofweek', - 'dayofyear', - 'decode', - 'default', - 'degrees', - 'des_decrypt', - 'des_encrypt', - 'elt', - 'encode', - 'encrypt', - 'exp', - 'export_set', - 'extract', - 'field', - 'find_in_set', - 'floor', - 'format', - 'found_rows', - 'from_days', - 'from_unixtime', - 'get_format', - 'get_lock', - 'group_concat', - 'greatest', - 'hex', - 'hour', - 'if', - 'ifnull', - 'in', - 'inet_aton', - 'inet_ntoa', - 'insert', - 'instr', - 'interval', - 'is_free_lock', - 'is_used_lock', - 'last_day', - 'last_insert_id', - 'lcase', - 'least', - 'left', - 'length', - 'ln', - 'load_file', - 'localtime', - 'localtimestamp', - 'locate', - 'log', - 'log2', - 'log10', - 'lower', - 'lpad', - 'ltrim', - 'make_set', - 'makedate', - 'maketime', - 'master_pos_wait', - 'match', - 'max', - 'md5', - 'microsecond', - 'mid', - 'min', - 'minute', - 'mod', - 'month', - 'monthname', - 'nextval', - 'now', - 'nullif', - 'oct', - 'octet_length', - 'old_password', - 'ord', - 'password', - 'period_add', - 'period_diff', - 'pi', - 'position', - 'pow', - 'power', - 'quarter', - 'quote', - 'radians', - 'rand', - 'release_lock', - 'repeat', - 'replace', - 'reverse', - 'right', - 'round', - 'row_count', - 'rpad', - 'rtrim', - 'sec_to_time', - 'second', - 'session_user', - 'sha', - 'sha1', - 'sign', - 'soundex', - 'space', - 'sqrt', - 'std', - 'stddev', - 'stddev_pop', - 'stddev_samp', - 'strcmp', - 'str_to_date', - 'subdate', - 'substring', - 'substring_index', - 'subtime', - 'sum', - 'sysdate', - 'system_user', - 'tan', - 'time', - 'timediff', - 'timestamp', - 'timestampadd', - 'timestampdiff', - 'time_format', - 'time_to_sec', - 'to_days', - 'trim', - 'truncate', - 'ucase', - 'uncompress', - 'uncompressed_length', - 'unhex', - 'unix_timestamp', - 'upper', - 'user', - 'utc_date', - 'utc_time', - 'utc_timestamp', - 'uuid', - 'var_pop', - 'var_samp', - 'variance', - 'version', - 'week', - 'weekday', - 'weekofyear', - 'year', - 'yearweek'); - - /* includes functions */ - $this->reserved = array( - 'abs', - 'acos', - 'adddate', - 'addtime', - 'aes_encrypt', - 'aes_decrypt', - 'against', - 'ascii', - 'asin', - 'atan', - 'avg', - 'benchmark', - 'bin', - 'bit_and', - 'bit_or', - 'bitcount', - 'bitlength', - 'cast', - 'ceiling', - 'char', - 'char_length', - 'character_length', - 'charset', - 'coalesce', - 'coercibility', - 'collation', - 'compress', - 'concat', - 'concat_ws', - 'conection_id', - 'conv', - 'convert', - 'convert_tz', - 'cos', - 'cot', - 'count', - 'crc32', - 'curdate', - 'current_user', - 'currval', - 'curtime', - 'database', - 'date_add', - 'date_diff', - 'date_format', - 'date_sub', - 'day', - 'dayname', - 'dayofmonth', - 'dayofweek', - 'dayofyear', - 'decode', - 'default', - 'degrees', - 'des_decrypt', - 'des_encrypt', - 'elt', - 'encode', - 'encrypt', - 'exp', - 'export_set', - 'extract', - 'field', - 'find_in_set', - 'floor', - 'format', - 'found_rows', - 'from_days', - 'from_unixtime', - 'get_format', - 'get_lock', - 'group_concat', - 'greatest', - 'hex', - 'hour', - 'if', - 'ifnull', - 'in', - 'inet_aton', - 'inet_ntoa', - 'insert', - 'instr', - 'interval', - 'is_free_lock', - 'is_used_lock', - 'last_day', - 'last_insert_id', - 'lcase', - 'least', - 'left', - 'length', - 'ln', - 'load_file', - 'localtime', - 'localtimestamp', - 'locate', - 'log', - 'log2', - 'log10', - 'lower', - 'lpad', - 'ltrim', - 'make_set', - 'makedate', - 'maketime', - 'master_pos_wait', - 'match', - 'max', - 'md5', - 'microsecond', - 'mid', - 'min', - 'minute', - 'mod', - 'month', - 'monthname', - 'nextval', - 'now', - 'nullif', - 'oct', - 'octet_length', - 'old_password', - 'ord', - 'password', - 'period_add', - 'period_diff', - 'pi', - 'position', - 'pow', - 'power', - 'quarter', - 'quote', - 'radians', - 'rand', - 'release_lock', - 'repeat', - 'replace', - 'reverse', - 'right', - 'round', - 'row_count', - 'rpad', - 'rtrim', - 'sec_to_time', - 'second', - 'session_user', - 'sha', - 'sha1', - 'sign', - 'soundex', - 'space', - 'sqrt', - 'std', - 'stddev', - 'stddev_pop', - 'stddev_samp', - 'strcmp', - 'str_to_date', - 'subdate', - 'substring', - 'substring_index', - 'subtime', - 'sum', - 'sysdate', - 'system_user', - 'tan', - 'time', - 'timediff', - 'timestamp', - 'timestampadd', - 'timestampdiff', - 'time_format', - 'time_to_sec', - 'to_days', - 'trim', - 'truncate', - 'ucase', - 'uncompress', - 'uncompressed_length', - 'unhex', - 'unix_timestamp', - 'upper', - 'user', - 'utc_date', - 'utc_time', - 'utc_timestamp', - 'uuid', - 'var_pop', - 'var_samp', - 'variance', - 'version', - 'week', - 'weekday', - 'weekofyear', - 'year', - 'yearweek', - 'add', - 'all', - 'alter', - 'analyze', - 'and', - 'as', - 'asc', - 'asensitive', - 'auto_increment', - 'bdb', - 'before', - 'berkeleydb', - 'between', - 'bigint', - 'binary', - 'blob', - 'both', - 'by', - 'call', - 'cascade', - 'case', - 'change', - 'char', - 'character', - 'check', - 'collate', - 'column', - 'columns', - 'condition', - 'connection', - 'constraint', - 'continue', - 'create', - 'cross', - 'current_date', - 'current_time', - 'current_timestamp', - 'cursor', - 'database', - 'databases', - 'day_hour', - 'day_microsecond', - 'day_minute', - 'day_second', - 'dec', - 'decimal', - 'declare', - 'default', - 'delayed', - 'delete', - 'desc', - 'describe', - 'deterministic', - 'distinct', - 'distinctrow', - 'div', - 'double', - 'drop', - 'else', - 'elseif', - 'enclosed', - 'escaped', - 'exists', - 'exit', - 'explain', - 'false', - 'fetch', - 'fields', - 'float', - 'for', - 'force', - 'foreign', - 'found', - 'frac_second', - 'from', - 'fulltext', - 'grant', - 'group', - 'having', - 'high_priority', - 'hour_microsecond', - 'hour_minute', - 'hour_second', - 'if', - 'ignore', - 'in', - 'index', - 'infile', - 'inner', - 'innodb', - 'inout', - 'insensitive', - 'insert', - 'int', - 'integer', - 'interval', - 'into', - 'io_thread', - 'is', - 'iterate', - 'join', - 'key', - 'keys', - 'kill', - 'leading', - 'leave', - 'left', - 'like', - 'limit', - 'lines', - 'load', - 'localtime', - 'localtimestamp', - 'lock', - 'long', - 'longblob', - 'longtext', - 'loop', - 'low_priority', - 'master_server_id', - 'match', - 'mediumblob', - 'mediumint', - 'mediumtext', - 'middleint', - 'minute_microsecond', - 'minute_second', - 'mod', - 'natural', - 'not', - 'no_write_to_binlog', - 'null', - 'numeric', - 'on', - 'optimize', - 'option', - 'optionally', - 'or', - 'order', - 'out', - 'outer', - 'outfile', - 'precision', - 'primary', - 'privileges', - 'procedure', - 'purge', - 'read', - 'real', - 'references', - 'regexp', - 'rename', - 'repeat', - 'replace', - 'require', - 'restrict', - 'return', - 'revoke', - 'right', - 'rlike', - 'second_microsecond', - 'select', - 'sensitive', - 'separator', - 'set', - 'show', - 'smallint', - 'some', - 'soname', - 'spatial', - 'specific', - 'sql', - 'sqlexception', - 'sqlstate', - 'sqlwarning', - 'sql_big_result', - 'sql_calc_found_rows', - 'sql_small_result', - 'sql_tsi_day', - 'sql_tsi_frac_second', - 'sql_tsi_hour', - 'sql_tsi_minute', - 'sql_tsi_month', - 'sql_tsi_quarter', - 'sql_tsi_second', - 'sql_tsi_week', - 'sql_tsi_year', - 'ssl', - 'starting', - 'straight_join', - 'striped', - 'table', - 'tables', - 'terminated', - 'then', - 'timestampadd', - 'timestampdiff', - 'tinyblob', - 'tinyint', - 'tinytext', - 'to', - 'trailing', - 'true', - 'undo', - 'union', - 'unique', - 'unlock', - 'unsigned', - 'update', - 'usage', - 'use', - 'user_resources', - 'using', - 'utc_date', - 'utc_time', - 'utc_timestamp', - 'values', - 'varbinary', - 'varchar', - 'varcharacter', - 'varying', - 'when', - 'where', - 'while', - 'with', - 'write', - 'xor', - 'year_month', - 'zerofill' - ); - - for($i = 0;$i < count($this->reserved);++$i) { - $this->reserved[$i] = strtoupper($this->reserved[$i]); - if(!empty($this->functions[$i])) $this->functions[$i] = strtoupper($this->functions[$i]); - } - } - -} // END CLASS diff --git a/gulliver/system/class.pmException.php b/gulliver/system/class.pmException.php index 47f855598..d5bb786de 100755 --- a/gulliver/system/class.pmException.php +++ b/gulliver/system/class.pmException.php @@ -1,18 +1,24 @@ * @package gulliver.system * @access public */ class PMException extends Exception { - public function __construct($message, $code = 0, $previous = null) { + + public function __construct ($message, $code = 0, $previous = null) + { //parent::__construct($message, 1, $previous); - parent::__construct($message, 1); + parent::__construct( $message, 1 ); } - public function __toString() { + public function __toString () + { return __CLASS__ . ": [{$this->code}]: {$this->message}\n"; } -} \ No newline at end of file +} + diff --git a/gulliver/system/class.xmlMenu.php b/gulliver/system/class.xmlMenu.php index c37667b59..216c74c9d 100755 --- a/gulliver/system/class.xmlMenu.php +++ b/gulliver/system/class.xmlMenu.php @@ -1,11 +1,13 @@ . - * - * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * along with this program. If not, see . + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., * Coral Gables, FL, 33134, USA, or email info@colosa.com. - * + * */ - /** +/** + * * @package gulliver.system */ - class xmlMenu extends form - { - var $type = 'xmlmenu'; - } +class xmlMenu extends form +{ + public $type = 'xmlmenu'; +} + +/** + * XmlForm_Field_XmlMenu + * + * extends XmlForm_Field + * + * @package gulliver.system + * + */ +class XmlForm_Field_XmlMenu extends XmlForm_Field +{ + public $xmlfile = ''; + public $type = 'xmlmenuDyn'; + public $xmlMenu; + public $home = ''; + public $withoutLabel = true; - /** - * XmlForm_Field_XmlMenu - * - * extends XmlForm_Field - * @package gulliver.system - * - */ - class XmlForm_Field_XmlMenu extends XmlForm_Field - { - var $xmlfile = ''; - var $type = 'xmlmenuDyn'; - var $xmlMenu; - var $home =''; - var $withoutLabel = true; - /** * XmlForm_Field_XmlMenu * - * @param string $xmlNode - * @param string $lang default value 'en' - * @param string $home default value '' - * @param string $owner + * @param string $xmlNode + * @param string $lang default value 'en' + * @param string $home default value '' + * @param string $owner * * @return none - */ - function XmlForm_Field_XmlMenu($xmlNode, $lang = 'en', $home = '', $owner) + */ + public function XmlForm_Field_XmlMenu ($xmlNode, $lang = 'en', $home = '', $owner = null) { - parent::XmlForm_Field($xmlNode, $lang, $home, $owner); - $this->home = $home; + parent::XmlForm_Field( $xmlNode, $lang, $home, $owner ); + $this->home = $home; } /** * render * - * @param string $value + * @param string $value * * @return object $out - */ - function render( $value ) - { - $this->xmlMenu = new xmlMenu( $this->xmlfile , $this->home ); - $this->xmlMenu->setValues($value); - $this->type = 'xmlmenuDyn'; - $template = PATH_CORE . 'templates/' . $this->type . '.html'; - $out = $this->xmlMenu->render( $template , $scriptCode ) ; - $oHeadPublisher =& headPublisher::getSingleton(); - $oHeadPublisher->addScriptFile( $this->xmlMenu->scriptURL ); - $oHeadPublisher->addScriptCode( $scriptCode ); - return $out; + */ + public function render ($value) + { + $this->xmlMenu = new xmlMenu( $this->xmlfile, $this->home ); + $this->xmlMenu->setValues( $value ); + $this->type = 'xmlmenuDyn'; + $template = PATH_CORE . 'templates/' . $this->type . '.html'; + $out = $this->xmlMenu->render( $template, $scriptCode ); + $oHeadPublisher = & headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile( $this->xmlMenu->scriptURL ); + $oHeadPublisher->addScriptCode( $scriptCode ); + return $out; } - + /** * renderGrid * - * @param string $value + * @param string $value * * @return none - */ - function renderGrid ($value) + */ + public function renderGrid ($value) { - return $this->render($value); + return $this->render( $value ); } +} - - }