PageRenderTime 37ms CodeModel.GetById 2ms app.highlight 28ms RepoModel.GetById 1ms app.codeStats 0ms

/com_qforms/admin/qforms.base.php

https://github.com/mcniac/mostly-joomla
PHP | 839 lines | 583 code | 67 blank | 189 comment | 111 complexity | 7a74aa45e34f640da34ca7d255866908 MD5 | raw file
  1<?php
  2/*
  3 *    This file is part of QForms
  4 *
  5 *    qForms is free software: you can redistribute it and/or modify
  6 *    it under the terms of the GNU General Public License as published by
  7 *    the Free Software Foundation, either version 3 of the License, or
  8 *    (at your option) any later version.
  9 *
 10 *    qForms is distributed in the hope that it will be useful,
 11 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13 *    GNU General Public License for more details.
 14 *
 15 *    You should have received a copy of the GNU General Public License
 16 *    along with qForms.  If not, see <http://www.gnu.org/licenses/>.
 17 */
 18
 19define('QFORMS_ACTION_LIST',    'list');
 20define('QFORMS_ACTION_VIEW',    'view');
 21define('QFORMS_ACTION_INSERT',  'insert');
 22define('QFORMS_ACTION_UPDATE',  'update');
 23define('QFORMS_ACTION_DELETE',  'delete');
 24define('QFORMS_ACTION_LISTFORM','listform');
 25define('QFORMS_ACTION_EXPORT',  'export');
 26define('QFORMS_ACTION_PRINT',   'print');
 27define('QFORMS_ACTION_WIZARD',  'wizard');
 28define('QFORMS_ACTION_FORM',    'form');
 29define('QFORMS_ACTION_PREVIEW', 'preview');
 30define('QFORMS_ACTION_PREVIEWDELETE', 'previewdelete');
 31
 32define('QFORMS_FILTER_EXACT',   '1');
 33define('QFORMS_FILTER_LIKE',    '2');
 34define('QFORMS_FILTER_RANGE',   '3');
 35define('QFORMS_FILTER_USER',    '4');
 36define('QFORMS_FILTER_NULL',    '5');
 37define('QFORMS_FILTER_ISZERO',  '6');
 38define('QFORMS_FILTER_EXACTSET','7');
 39
 40define('QFORMS_RENDER_STATIC',  '1');
 41define('QFORMS_RENDER_CONTROL', '2');
 42define('QFORMS_RENDER_HIDDEN',  '3');
 43
 44/**
 45* Load the widget classes and other helpers.
 46**/
 47require_once(QFORMS_PATH.'qforms.widgets.php');
 48if(!function_exists('adodb_date_test_date')) {
 49    require_once(QFORMS_PATH.'adodb-time.inc.php');
 50}
 51
 52class   QFormsBase {
 53    /**
 54    * Define filters, permission, etc.
 55    **/
 56    function    Init() {
 57        $this->currAction   = QFORMS_ACTION_LIST;
 58        $this->currRecord   = null;
 59
 60        $this->abm_fields   = array();
 61        $this->abm_errors   = array();
 62        $this->abm_data     = array();
 63        $this->gpc_data     = array();
 64        $this->abm_filters  = array();
 65        $this->abm_hiddens  = array();
 66        $this->abm_sorters  = array();
 67
 68        $this->abm_title    = '';
 69        $this->abm_subtitle = '';
 70        $this->abm_pageNo       = 1;
 71        $this->abm_pageCount    = 1;
 72        $this->abm_orderBy      = null;
 73        $this->abm_rowsPerPage  = 50;
 74        $this->abm_submitted    = false;
 75        $this->abm_limit        = array();
 76        $this->abm_curr_rid     = 0;
 77        if( !isset($this->abm_prefix) )
 78        	$this->abm_prefix       = 'xF_';
 79        #echo $this->abm_prefix;
 80        $this->perm_list    = true;
 81        $this->perm_view    = true;
 82        $this->perm_insert  = true;
 83        $this->perm_update  = true;
 84        $this->perm_delete  = true;
 85        $this->perm_listform= true;
 86        $this->perm_export  = true;
 87        $this->perm_print   = true;
 88        $this->controls_before = true; // define que los controles del formulario esten delante en el modo grilla
 89        $this->qforms_language  = $GLOBALS['qforms_default_language'] = 'en';
 90        $this->confirm_reload   = 1; // tiempo en segundos (0-infinito) para recargar. -1 desactiva
 91        $this->confirm_html     = null;
 92        $this->sql_engine       = null;
 93        $this->allow_unchanged_submits = false;
 94
 95        $this->abm_url          = QForms::URL($_SERVER['REQUEST_URI']);
 96
 97        $base_url               = QForms::URL($this->abm_url, array(
 98            $this->abm_prefix.'action' => null,
 99            $this->abm_prefix.'record' => null,
100            ));
101        $this->abm_view_url     = "$base_url&{$this->abm_prefix}action=". QFORMS_ACTION_VIEW;
102        $this->abm_insert_url   = "$base_url&{$this->abm_prefix}action=". QFORMS_ACTION_INSERT;
103        $this->abm_update_url   = "$base_url&{$this->abm_prefix}action=". QFORMS_ACTION_UPDATE;
104        $this->abm_delete_url   = "$base_url&{$this->abm_prefix}action=". QFORMS_ACTION_DELETE;
105        $this->abm_previewdelete_url   = "$base_url&{$this->abm_prefix}action=". QFORMS_ACTION_PREVIEWDELETE;
106        $this->abm_back_url     = null;
107        $this->abm_confirm_url  = null;
108        $this->html_delete_confirmation = true;
109
110        $this->abm_export_url   = QForms::URL($this->abm_url, array(
111            $this->abm_prefix.'action'=>QFORMS_ACTION_EXPORT,
112            $this->abm_prefix.'Module'=>basename($_SERVER['SCRIPT_FILENAME'])
113            ),null,'qforms.generic.export_print.php');
114        $this->abm_print_url    = QForms::URL($this->abm_url, array(
115            $this->abm_prefix.'action'=>QFORMS_ACTION_PRINT,
116            $this->abm_prefix.'Module'=>basename($_SERVER['SCRIPT_FILENAME'])
117             ),null,'qforms.generic.export_print.php');
118
119        $this->abm_listform_url = QForms::URL($this->abm_url,$this->abm_prefix.'action', QFORMS_ACTION_LISTFORM);
120        $this->abm_list_url     = QForms::URL($this->abm_url,$this->abm_prefix.'action', QFORMS_ACTION_LIST);
121
122        $this->template_list    = QFORMS_PATH_TEMPLATES.'qforms.template.list.php';
123        $this->template_form    = QFORMS_PATH_TEMPLATES.'qforms.template.form.php';
124        $this->template_confirm = QFORMS_PATH_TEMPLATES.'qforms.template.confirm.php';
125        $this->template_export  = QFORMS_PATH_TEMPLATES.'qforms.template.export.php';
126        $this->template_print   = QFORMS_PATH_TEMPLATES.'qforms.template.print.php';
127
128        $this->rows_total       = 0;
129        $this->flag_confirm     = false;
130        $this->abm_pk_expr      = null;
131        $this->wizard_count     = null;
132        $this->wizard_step      = null;
133
134        /**
135        * GPC: Load action & misc info
136        **/
137        if( ($t=@strval($_GET[$this->abm_prefix.'action'])) )   $this->currAction = $t;
138        if( ($t=@strval($_GET[$this->abm_prefix.'record'])) )   $this->currRecord = $t;
139        if( ($t=@strval($_GET[$this->abm_prefix.'backUrl'])) )  $this->abm_back_url = $t;
140        if( ($t=@strval($_GET[$this->abm_prefix.'confirmUrl'])))$this->abm_confirm_url = $t;
141        if($this->html_delete_confirmation)
142        	$this->abm_delete_url   = QForms::URL($this->abm_delete_url,$this->abm_prefix.'backUrl', urlencode($this->abm_back_url));
143        $this->abm_submitted = !empty($_POST[$this->abm_prefix.'SubmitData']);
144        $this->message = '';
145        if( $this->currAction==QFORMS_ACTION_LISTFORM )
146        	$this->message = QForms::trans("Remember to click on the save button in order to apply the changes you made");
147    }
148
149    /**
150    * Helper function
151    **/
152    function    _widgets_sort(&$a,&$b) {
153        $al = sprintf('%s |%4.4d',strtolower($a->field_group), $a->field_order);
154        $bl = sprintf('%s |%4.4d',strtolower($b->field_group), $b->field_order);
155        if($al == $bl) return 0;
156        return (($al > $bl) ? +1 : -1);
157    }
158
159    /**
160    * Internal initialization
161    **/
162    function    Prepare() {
163        uasort($this->abm_filters,array(&$this,'_widgets_sort'));
164        /**
165        * GPC: Load filters, pagination, order
166        **/
167        foreach(array_keys($this->abm_filters) as $name) {
168            $this->abm_filters[$name]->abm = &$this;
169            $this->abm_filters[$name]->Init();
170            if( ($t=$this->abm_filters[$name]->loadGPC('xFF_', true))!==null ) {
171                $this->abm_filters[$name]->value = $t;
172            }
173        }
174        if( ($t=@strval($_GET[$this->abm_prefix.'pageNo'])) )       $this->abm_pageNo       = $t;
175        if( ($t=@strval($_GET[$this->abm_prefix.'RowsPerPage'])) )  $this->abm_rowsPerPage  = $t;
176        if( ($t=@strval($_GET[$this->abm_prefix.'orderBy'])) )      $this->abm_orderBy      = $t;
177    }
178
179    /**
180    * TODO: COMMENT
181    **/
182    function    dataLoad($from_db=false, $from_defaults=false, $force_defaults=false) {
183        if($from_db) {
184            if($this->currRecord) {
185                $this->abm_data     = array($this->data_select(false, $this->currRecord));
186            }else{
187                $this->rows_total       = $this->data_select(true);
188                $this->abm_pageCount    = ceil( $this->rows_total / $this->abm_rowsPerPage);
189                if($this->abm_pageNo<1)
190                    $this->abm_pageNo=1;
191                if($this->abm_pageNo>$this->abm_pageCount)
192                    $this->abm_pageNo=$this->abm_pageCount;
193                $this->abm_limit    = array(
194                    (($this->abm_pageNo>0)?(($this->abm_pageNo-1)*$this->abm_rowsPerPage):0),
195                    $this->abm_rowsPerPage );
196                if($this->rows_total)
197                    $this->abm_data     = $this->data_select();
198            }
199        }
200        if($from_defaults) {
201            if($force_defaults && empty($this->abm_data))
202                $this->abm_data[0]=array();
203            foreach($this->abm_data as $rid=>$rec) {
204                foreach(array_keys($this->abm_fields) as $k) {
205                	if( !isset($rec[$k]) && !is_null($t=$this->abm_fields[$k]->GetDefault() ) ) {
206                        $this->abm_data[$rid][$k] = $t;
207                    }
208                }
209            }
210        }
211    }
212
213    /**
214    * Read the name...
215    **/
216    function    Validate() {
217        foreach($this->gpc_data as $rid=>$rec) {
218            foreach($this->GetFieldList( 'visible' ) as $name) {
219                if( ($t=$this->abm_fields[$name]->Validate( $this->getFieldValue($name,$rid) )) )
220                    $this->abm_errors[] = $t;
221            }
222            $this->ValidateRec($this->getData($rid), $this->getDataDiff($rid), $this->getPK($rid,$rec), $rid);
223        }
224        return empty($this->abm_errors);
225    }
226
227    /**
228    * GPC: Load fields data.
229    **/
230    function    loadGPC() {
231        $dirty=false;
232        foreach($this->abm_data as $rid=>$rec) {
233            $this->gpc_data[$rid]=array();
234            foreach(array_keys($this->abm_fields) as $k) {
235            	//printf("<li>loadGPC: %s|%s</li>", $k, $this->abm_fields[$k]->loadGPC( $this->getWidgetName($k,$rid) ));
236                if( ($t=$this->abm_fields[$k]->loadGPC( $this->getWidgetName($k,$rid) ))!==null ) {
237                    $this->gpc_data[$rid][$k] = $t;
238                    $dirty = true;
239                }
240            }
241        }
242
243        /**
244        * This nifty little piece of code might look a bit complicated...
245        **/
246        $this->abm_result_data      = array();
247        $this->abm_result_dataDiff  = array();
248
249        foreach($this->gpc_data as $rid=>$rec) {
250            $this->abm_result_data[$rid] = array();
251            foreach(array_keys($this->abm_fields) as $name) {
252                if(!$this->abm_fields[$name]->is_static) {
253                    $value=array('lasdhkq7812#!@#*34y78134 asdfS ]X ;sdkhhgh');
254                    if( isset($rec[$name]) ) {
255                        $value = $rec[$name];
256                        if(empty($value) && $this->abm_fields[$name]->is_null) $value=null;
257                        //printf("<li>POSTED rid=%s name=%s data=%s value=%s</li>\n", $rid, $name, @$this->abm_data[$rid][$name], @$value, @$this->abm_result_data[$rid][$name]);
258                    }else{
259                        //printf("<li>DEFAULT rid=%s name=%s data=%s value=%s</li>\n", $rid, $name, @$this->abm_data[$rid][$name], @$value, @$this->abm_result_data[$rid][$name]);
260                        $value = @$this->abm_data[$rid][$name];
261                    }
262
263                    if($value!==array('lasdhkq7812#!@#*34y78134 asdfS ]X ;sdkhhgh')) {
264                        if(empty($value) && $this->abm_fields[$name]->is_null) $value=null;
265                        $this->abm_fields[$name]->ProcessValue($value);
266                        @$this->abm_result_data[$rid][$name] = $value;
267                        @$this->abm_result_dataDiff[$rid][$name] = $value;
268
269                        //printf("<li>Change rid=%s name=%s data=%s value=%s</li>\n", $rid, $name, @$this->abm_data[$rid][$name], @$value, @$this->abm_result_data[$rid][$name]);
270                    }else{
271                        //printf("<li>.... WRONG(?) rid=%s name=%s data=%s value=%s</li>\n", $rid, $name, @$this->abm_data[$rid][$name], @$value, @$this->abm_result_data[$rid][$name]);
272                    }
273                }
274            }
275        }
276/** Modo anterior, tratando de detectar cambios... no funciona muy bien
277        foreach($this->gpc_data as $rid=>$rec) {
278            $this->abm_result_data[$rid] = array();
279            foreach(array_keys($this->abm_fields) as $name) {
280                if(!$this->abm_fields[$name]->is_static) {
281                    $value=array('lasdhkq7812#!@#*34y78134 asdfS ]X ;sdkhhgh');
282                    $flag_changed=false;
283					//printf("<li>Checking: |%s|%s|%s|</li>\n", $rid, $name, $this->abm_data[$rid][$name]);
284                    if( isset($rec[$name]) ) {
285                        $value = $rec[$name];
286                        if(empty($value) && $this->abm_fields[$name]->is_null)
287                            $value=null;
288                        //printf("<li>Changed: |%s|%s|%s|%s|</li>\n", $rid, $name, $this->abm_data[$rid][$name], $value);
289                        $flag_changed = (!isset($this->abm_data[$rid][$name])&&!is_null(@$this->abm_data[$rid][$name]) || @$this->abm_data[$rid][$name]!==$value);
290                    }else{
291                        $value = @$this->abm_data[$rid][$name];
292                    }
293                    if($value!==array('lasdhkq7812#!@#*34y78134 asdfS ]X ;sdkhhgh')) {
294                        if(empty($value) && $this->abm_fields[$name]->is_null)
295                            $value=null;
296                        $this->abm_fields[$name]->ProcessValue($value);
297                        @$this->abm_result_data[$rid][$name] = $value;
298                        if($flag_changed) {
299                            @$this->abm_result_dataDiff[$rid][$name] = $value;
300                            //printf("<li>Diff: |%s|%s|%s|%s|%s|</li>\n", $rid, $name, $this->abm_data[$rid][$name], $value, $this->abm_result_data[$rid][$name]);
301                        }
302                    }
303                }
304            }
305        }
306*/
307        return $dirty;
308    }
309
310    /**
311    * Data validation & processing
312    **/
313    function    Process() {
314        /**
315        * Initialize widgets & prepare the PK expression
316        **/
317        uasort($this->abm_fields, array(&$this,'_widgets_sort'));
318
319        $exprs  = array();
320        foreach(array_keys($this->abm_fields) as $name) {
321            $this->abm_fields[$name]->abm = &$this;
322            $this->abm_fields[$name]->Init();
323            if($this->abm_fields[$name]->abm_pk_order) {
324                $exprs[] = "'$name'=>\$rec['$name']";
325            }
326        }
327        if($exprs) {
328            $this->abm_pk_expr = 'array('.implode(",",$exprs).')';
329            /**
330            * In case of a 'complex' (more than one field) PK, decode it
331            **/
332            if(count($exprs)>1) {
333                $currPk = explode('|', $this->currRecord);
334                $this->currRecord=array();
335                $order=0;
336                foreach(array_keys($this->abm_fields) as $k) {
337                    if($t=$this->abm_fields[$k]->abm_pk_order) {
338                        $this->currRecord[$k]=stripcslashes(@$currPk[$order++]);
339                    }
340                }
341            }
342        }
343
344        /**
345        * Execute the corresponding action
346        **/
347        $data=false;
348        switch($this->currAction) {
349        case QFORMS_ACTION_INSERT:
350            $this->ERROR_ON( !$this->perm_insert, QForms::trans("Access right error"));
351            $this->dataLoad(false,true, true);
352
353            #HACK DATAOBJECTS:
354            if($this->abm_submitted && $this->loadGPC() && $this->Validate()) {
355                $this->flag_confirm = $this->data_insert($this->getData());
356            }
357
358            #if($this->abm_submitted && $this->loadGPC() && $this->Validate() && (($data=$this->getData())||$this->allow_unchanged_submits) && $this->data_insert( $data ) ) {
359            #    $this->flag_confirm = true;
360            #}elseif(is_null(@$data)) {
361            #    $this->abm_errors[] = QForms::trans("No changes to perform");
362            #}
363            break;
364        case QFORMS_ACTION_UPDATE:
365            $this->ERROR_ON( !$this->perm_update, QForms::trans("Access right error") );
366            $this->ERROR_ON( !$this->currRecord,  QForms::trans("Missing record") );
367            $this->dataLoad(true,true);
368
369            #HACK DATAOBJECTS:
370            if($this->abm_submitted && $this->loadGPC() && $this->Validate()) {
371                $this->flag_confirm = $this->data_update( $this->currRecord, $this->getData() );
372            }
373            #if($this->abm_submitted && $this->loadGPC() && $this->Validate() && (($data=$this->getDataDiff())||$this->allow_unchanged_submits) && $this->data_update( $this->currRecord, $data ) ) {
374            #    $this->flag_confirm = true;
375            #}elseif(is_null(@$data)) {
376            #    $this->abm_errors[] = QForms::trans("No changes to perform");
377            #}
378            break;
379        case QFORMS_ACTION_DELETE:
380            $this->ERROR_ON( !$this->perm_delete, QForms::trans("Access right error") );
381            $this->ERROR_ON( !$this->currRecord,  QForms::trans("Missing record") );
382            $this->dataLoad(true,false);
383
384            if(!$this->abm_back_url) $this->abm_back_url=$this->abm_list_url;
385            if(!$this->abm_confirm_url) $this->abm_confirm_url=$this->abm_list_url;
386
387            if( !$this->html_delete_confirmation || $this->abm_submitted) {
388            	if($this->html_delete_confirmation)
389            		$this->abm_list_url = $this->abm_confirm_url;
390                if( $this->data_delete( $this->currRecord ) )
391                    $this->flag_confirm = true;
392            }
393            break;
394        case QFORMS_ACTION_VIEW:
395            $this->ERROR_ON( !$this->perm_view, QForms::trans("Access right error") );
396            $this->ERROR_ON( !$this->currRecord,  QForms::trans("Missing record") );
397            $this->dataLoad(true, true);
398            break;
399        case QFORMS_ACTION_PREVIEWDELETE:
400            $this->ERROR_ON( !$this->perm_delete, QForms::trans("Access right error") );
401            $this->ERROR_ON( !$this->perm_view, QForms::trans("Access right error") );
402            $this->ERROR_ON( !$this->currRecord,  QForms::trans("Missing record") );
403            $this->dataLoad(true, true);
404            break;
405        case QFORMS_ACTION_FORM:
406            $this->ERROR_ON( !$this->perm_update, QForms::trans("Access right error") );
407            $this->dataLoad(true,true);
408            if($this->abm_submitted && $this->loadGPC() && $this->Validate() && ($data=$this->getDataDiff()) ) {
409                $this->data_update( $this->currRecord, $data );
410                $this->flag_confirm = true;
411            }elseif(empty($this->allow_empty_changes)&&is_null(@$data)) {
412                $this->abm_errors[] = QForms::trans("No changes to perform");
413            }else{
414                // for forms, always try to fetch the data
415                if($this->loadGPC())
416                    $this->Validate();
417            }
418            break;
419        case QFORMS_ACTION_PREVIEW:
420            $this->ERROR_ON( !$this->perm_view, QForms::trans("Access right error") );
421            $this->ERROR_ON( !$this->currRecord,  QForms::trans("Missing record") );
422            $this->dataLoad(true,true);
423            if( $this->loadGPC() && $this->Validate() && ($data=$this->getDataDiff()) ) {
424                $this->data_preview( $this->currRecord, $data );
425            }else{
426                $this->abm_errors[] = QForms::trans("Fatal");
427            }
428            break;
429        case QFORMS_ACTION_LISTFORM:
430            $this->ERROR_ON( !$this->perm_listform, QForms::trans("Access right error") );
431            $this->currRecord = null;
432            $this->dataLoad(true, false);
433
434            if($this->abm_submitted && $this->loadGPC() && $this->Validate() && ($alldata = $this->getDataDiff(null)) ) {
435                $allok=true;
436                foreach($alldata as $rid=>$data) {
437                    $allok = $allok && $this->data_update( $this->getPK($rid), $data , $rid);
438                }
439                if($allok)
440                $this->flag_confirm = true;
441            }
442            break;
443        case QFORMS_ACTION_WIZARD:
444            $this->dataLoad(true,true);
445            $this->loadGPC();
446            $wizard_next = !empty($_POST[$this->abm_prefix.'WizardNext']);
447            $wizard_prev = !empty($_POST[$this->abm_prefix.'WizardPrev']);
448            unset($_POST[$this->abm_prefix.'WizardNext']);
449            unset($_POST[$this->abm_prefix.'WizardPrev']);
450            if($wizard_next && $this->wizard_step<$this->wizard_count) {
451                if($this->Validate()) {
452                    $this->WizardData($this->getData());
453                    $this->wizard_step++;
454                    return true;
455                }
456            }elseif($wizard_prev && $this->wizard_step>1){
457                $this->WizardData($this->getData());
458                $this->wizard_step--;
459                return true;
460            }elseif( $this->abm_submitted && $this->Validate() ) {
461                $this->WizardData($this->getData());
462                $this->data_update( $this->currRecord, $this->WizardData() );
463                $this->flag_confirm = true;
464                return false;
465            }
466            break;
467        default:
468            $this->ERROR_ON( !$this->perm_list, QForms::trans("Access right error") );
469            $this->currRecord = null;
470            $this->dataLoad(true, true);
471        }
472        return $this->flag_confirm;
473    }
474
475    /**
476    * TODO: COMMENT
477    **/
478    function    GetFilterList( $type ) {
479        $set=array();
480        switch($type) {
481        case 'visible':
482            foreach(array_keys($this->abm_filters) as $name)
483                if($this->abm_filters[$name]->is_visible && !$this->abm_filters[$name]->abm_filter_fixed)
484                    $set[] = $name;
485            break;
486        case 'hidden':
487            foreach(array_keys($this->abm_filters) as $name)
488                if(!$this->abm_filters[$name]->is_visible || $this->abm_filters[$name]->abm_filter_fixed)
489                    $set[] = $name;
490            break;
491        }
492        return $set;
493    }
494
495    /**
496    * TODO: COMMENT
497    **/
498    function    GetSortList() {
499        $set    = $this->abm_sorters;
500        foreach(array_keys($this->abm_fields) as $name) {
501            $r=array();
502
503            if( preg_match('/(?<![a-z0-9_])sortable(:[^\s]+)?(?![a-z0-9_])/', implode(' ',$this->abm_fields[$name]->_TAGS),$r) ) {
504                $fname              = htmlspecialchars((!empty($r[1]))?substr($r[1],1):$name);
505                $caption            = $this->abm_fields[$name]->caption;
506                $set[ $fname ]      = $caption;
507                $set[ "$fname*" ]   = "$caption (desc)";
508            }
509        }
510        return $set;
511    }
512    /**
513    * TODO: COMMENT
514    **/
515    function    GetFieldList( $type ) {
516        $set    = array();
517        $tags = array('no_'.$this->currAction);
518
519        foreach(array_keys($this->abm_fields) as $name) {
520            if( array_intersect($this->abm_fields[$name]->_TAGS,array('static_'.$this->currAction)) )
521                $this->abm_fields[$name]->is_static=true;
522        }
523
524        switch($type) {
525        case 'loadable':
526            foreach(array_keys($this->abm_fields) as $name) {
527                if($this->abm_fields[$name]->is_static && !array_intersect($this->abm_fields[$name]->_TAGS,$tags) )
528                    $set[] = $name;
529            }
530            break;
531        case 'writable':
532            foreach(array_keys($this->abm_fields) as $name) {
533                if(!$this->abm_fields[$name]->is_static && !$this->abm_fields[$name]->is_readonly && !array_intersect($this->abm_fields[$name]->_TAGS,$tags) )
534                    $set[] = $name;
535            }
536            break;
537        case 'visible':
538            foreach(array_keys($this->abm_fields) as $name) {
539                if($this->abm_fields[$name]->is_visible && !array_intersect($this->abm_fields[$name]->_TAGS,$tags))
540                    $set[] = $name;
541            }
542            break;
543        case 'hidden':
544            foreach(array_keys($this->abm_fields) as $name)
545                if(!$this->abm_fields[$name]->is_visible)
546                    $set[] = $name;
547            break;
548        default:
549            foreach(array_keys($this->abm_fields) as $name)
550                $set[] = $name;
551            break;
552        }
553        return $set;
554    }
555
556    /**
557    * TODO: COMMENT
558    **/
559    function    RenderField( $name, $rid, $mode=QFORMS_RENDER_CONTROL ) {
560        $this->abm_curr_rid = $rid;
561        $prefix = $this->getWidgetName($name,$rid);
562        $value  = $this->getFieldValue($name,$rid);
563
564        if($mode==QFORMS_RENDER_HIDDEN) {
565            $class = null;
566            $html = $this->abm_fields[$name]->htmlHidden( $prefix , $value );
567        }else{
568        	if($mode==QFORMS_RENDER_STATIC && !empty($this->abm_fields[$name]->is_list_control) )
569        		$mode=QFORMS_RENDER_CONTROL;
570
571            list($class,$html) = $this->abm_fields[$name]->Display( $prefix , $value, ($mode==QFORMS_RENDER_STATIC) );
572        }
573        $t=(array)$this->abm_fields[$name];
574        $t['caption'       ] = $this->abm_fields[$name]->caption;
575        $t['html'          ] = $html;
576        $t['id'            ] = $prefix.$name;
577        $t['class'         ] = $class;
578        $t['value'         ] = $value;
579        $t['_TAGS'         ] = @$this->abm_fields[$name]->_TAGS;
580		$t['type'		   ] = substr(strtolower(get_class($this->abm_fields[$name])),13);
581        $t['description'   ] = $this->abm_fields[$name]->description;
582        $t['group'         ] = $this->abm_fields[$name]->field_group;
583        return $t;
584    }
585    /**
586    * TODO: COMMENT
587    **/
588    function    RenderFilter( $name, $mode=QFORMS_RENDER_CONTROL ) {
589        $this->abm_filters[$name]->abm = &$this;
590        $value  = $this->abm_filters[$name]->value;
591        if($mode==QFORMS_RENDER_HIDDEN) {
592            $class = null;
593            $html = $this->abm_filters[$name]->htmlHidden( 'xFF_' , $value );
594        }else{
595            list($class,$html) = $this->abm_filters[$name]->Display( 'xFF_' , $value, ($mode==QFORMS_RENDER_STATIC) );
596        }
597        return array(
598            'caption'   => htmlspecialchars($this->abm_filters[$name]->caption),
599            'html'      => $html,
600            'class'     => $class,
601            'value'     => $value,
602            '_TAGS'         => $this->abm_filters[$name]->_TAGS,
603			'type'			 => substr(strtolower(get_class($this->abm_filters[$name])),13),
604            'description'   => $this->abm_filters[$name]->description,
605            'group'         => $this->abm_filters[$name]->field_group
606            );
607    }
608
609    /**
610    * TODO: COMMENT
611    **/
612    function    addField($obj, $pk_order=0) {
613    	//echo $obj->name;
614        #$this->ERROR_ON(isset($this->abm_fields[$obj->name]), QForms::trans("Error. Duplicated field").': '.$obj->name );
615        $obj->abm_pk_order = $pk_order;
616        $obj->abm = & $this;
617        if(is_null($obj->field_order)) $obj->field_order=count($this->abm_fields);
618        if(is_null($obj->field_listord)) $obj->field_listord=count($this->abm_fields);
619        $this->abm_fields[$obj->name] = $obj;
620    }
621
622    /**
623    * TODO: COMMENT
624    **/
625    function    addFilter($obj, $filter_type, $fixed_filter=false) {
626        #$this->ERROR_ON(isset($this->abm_filters[$obj->name]), QForms::trans("Error. Duplicated filter") );
627        $obj->abm_filter_type   = $filter_type;
628        $obj->abm_filter_fixed  = $fixed_filter;
629        if(is_null($obj->field_order)) $obj->field_order=count($this->abm_filters);
630        $this->abm_filters[$obj->name] = $obj;
631    }
632
633    /**
634    * TODO: COMMENT
635    **/
636    function    addHidden($name, $value) {
637        $this->abm_hiddens[$name] = $value;
638    }
639
640    /**
641    * TODO: COMMENT
642    **/
643    function    getFieldValue($name, $row=null) {
644        if($row===null) $row=$this->abm_curr_rid;
645        return (isset($this->abm_result_data[$row][$name])
646            ?$this->abm_result_data[$row][$name]
647            :@$this->abm_data[$row][$name]);
648    }
649
650    /**
651    * TODO: COMMENT
652    **/
653    function    getFilterValue($name) {
654        return $this->abm_filters[$name]->value;
655    }
656
657    /**
658    * TODO: COMMENT
659    **/
660    function    getWidgetName($name, $rid=null) {
661        return $this->abm_prefix.($rid?"_{$rid}_":"");
662    }
663
664    /**
665    * TODO: COMMENT
666    **/
667    function    getPK($rid, $rec=null, $encoded=false) {
668        $pk = array();
669        if(!$rec) $rec = @$this->abm_data[$rid];
670        if($rec) {
671            $pk = @eval("return $this->abm_pk_expr;");
672            if(count($pk)==1) $pk = reset($pk);
673        }
674        if($encoded) {
675            if(is_array($pk)){
676                foreach($pk as $k=>$v) $pk[$k] = addcslashes($v,'|');
677                $pk = urlencode(implode('|',$pk));
678            }else{
679                $pk = urlencode($pk);
680            }
681        }
682        return $pk;
683    }
684
685    /**
686    * TODO: COMMENT
687    **/
688    function    getPKNames($pk) {
689        foreach(array_keys($this->abm_fields) as $name) {
690            $this->abm_fields[$name]->abm = &$this;
691            $this->abm_fields[$name]->Init();
692            if($this->abm_fields[$name]->abm_pk_order) {
693                return array($name=>$pk);
694            }
695        }
696        return array();
697    }
698
699    /**
700    * TODO: COMMENT
701    **/
702    function    getData($rid=0) {
703        if($rid!==null) return @$this->abm_result_data[$rid];
704        return $this->abm_result_data;
705    }
706
707    /**
708    * TODO: COMMENT
709    **/
710    function    getDataDiff($rid=0) {
711        if($rid!==null) return @$this->abm_result_dataDiff[$rid];
712        return $this->abm_result_dataDiff;
713    }
714
715    /**
716    * TODO: COMMENT
717    **/
718    function    WizardData($set=null, $clean=false) {
719        if($clean||empty($_SESSION[$this->abm_prefix."WSESS $this->abm_title data"]))
720            $_SESSION[$this->abm_prefix."WSESS $this->abm_title data"]=array();
721        if($set)
722            $_SESSION[$this->abm_prefix."WSESS $this->abm_title data"] = array_merge(@$_SESSION[$this->abm_prefix."WSESS $this->abm_title data"],$set);
723        return @$_SESSION[$this->abm_prefix."WSESS $this->abm_title data"];
724    }
725
726    function    ValidateRec($data, $dataDiff, $pk=null, $rid=null) {
727        return empty($this->abm_errors);
728    }
729    function    ValidateRecJS_callback($m) {
730        switch($m[1]) {
731        case 'idOf': return $this->abm_prefix.$this->abm_fields[$m[2]]->name;
732        case 'valueOf': return str_replace('@abm_prefix@', $this->abm_prefix, $this->abm_fields[$m[2]]->js_getValue);
733        case 'nameOf':  return addslashes ( ($this->abm_fields[$m[2]]->field_group?"(".$this->abm_fields[$m[2]]->field_group.") ":"").$this->abm_fields[$m[2]]->caption );
734        case 'fieldExists':  return $this->abm_fields[$m[2]]->caption;
735        }
736        return null;
737    }
738    function    ValidateRecJS( $items=array() ) {
739        $visible_fields     = $this->GetFieldList( 'visible' );
740        foreach($visible_fields as $name) {
741            if($t=$this->abm_fields[$name]->jsValidate()) {
742                $items=array_merge($items,$t);
743            }
744        }
745        $items =  preg_replace_callback('/@(\w+) (\w+)@/', array(&$this,'ValidateRecJS_callback'),
746            implode(";\n",$items) );
747        //$items =  preg_replace_callback('/@(nameOf) (\w+)@/',
748        //    create_function('$m', 'return $this->abm_fields[$m[1]]->caption;'),
749        //    $items );
750        if($items)
751        $items = "
752<script type=\"text/javascript\" >
753function xF_Value(elt,name) {var t=null; if(!name) name=elt.name; if(t=elt.form.elements[name]) { if(t.options) return t.options[t.selectedIndex].value; else return t.value; } }
754function xF_Validate(xF_Form) {
755   	var errores=[];
756
757$items
758
759	var errorMsg='';
760	for(var i=0 ; i<errores.length ; i++)
761		if(errores[i]) errorMsg+=''+errores[i];
762	if(errorMsg) {
763		if(t=document.getElementById('xfABMErrors'))
764			t.innerHTML=errorMsg.replace(/\\r?\\n/,'<br>');
765			alert(errorMsg); return false;
766		}
767	return true;
768}
769</script>";
770        return $items;
771    }
772
773    /**
774    * Main loop. This is the method one has to override.
775    **/
776    function    Run() {
777        $this->Init();
778
779        /**
780        * Define filters, permission and options HERE
781        **/
782
783        $this->Prepare();
784
785        /**
786        * Define columns HERE
787        **/
788
789        $this->Process();
790
791        /**
792        * Usually Display is called elsewhere...
793        **/
794    }
795
796    /**
797    * TODO: COMMENT
798    **/
799    function    data_select($do_count=false, $pk=null) {
800        if($do_count) {
801            return 0;
802        }elseif($pk) {
803            return array();
804        }else{
805            return array();
806        }
807    }
808
809    /**
810    * TODO: COMMENT
811    **/
812    function    data_insert($data) {
813        echo "<p>data_insert(".var_export($data,true).");</p>\n";
814    }
815
816    /**
817    * TODO: COMMENT
818    **/
819    function    data_update($pk, $data) {
820        echo "<p>data_update(".var_export($pk,true).",".var_export($data,true).");</p>\n";
821    }
822
823    /**
824    * TODO: COMMENT
825    **/
826    function    data_delete($pk) {
827        echo "<p>data_delete(".var_export($pk,true).");</p>\n";
828    }
829
830    /**
831    * TODO: COMMENT
832    **/
833    function    data_preview($pk, $data) {
834        echo "<p>data_preview(".var_export($pk,true).",".var_export($data,true).");</p>\n";
835    }
836
837}
838
839?>