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 );
}
+}
-
- }