/[cvs]/nfo/php/libs/com.newsblob.phphtmllib/widgets/data_list/DataList.inc
ViewVC logotype

Annotation of /nfo/php/libs/com.newsblob.phphtmllib/widgets/data_list/DataList.inc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (hide annotations)
Thu Feb 13 00:40:51 2003 UTC (21 years, 6 months ago) by joko
Branch: MAIN
CVS Tags: v2-1-3
Changes since 1.3: +1 -1 lines
+- renamed modules

1 jonen 1.1 <?php
2    
3     /**
4     * This is the base class for managing a list
5     * of data points.
6     *
7     * @author Walter A. Boring IV <waboring@buildabetterweb.com>
8     * @package phpHtmlLib
9     */
10    
11     define("SORTABLE", TRUE);
12     define("NOT_SORTABLE", FALSE);
13     define("SEARCHABLE", TRUE);
14     define("NOT_SEARCHABLE", FALSE);
15    
16     //Some defines for setting up the search
17     //modifier fields.
18     define("SEARCH_BEGINS_WITH", 1);
19     define("SEARCH_CONTAINS", 2);
20     define("SEARCH_EXACT", 4);
21     define("SEARCH_ENDS_WITH", 8);
22     define("SEARCH_ALL", 15);
23    
24    
25     /**
26     * This object is the base class that can be
27     * used to build a widget that shows lists of
28     * data from any source via the DataListSource
29     * object. It fetches/builds/gets its data
30     * from the DataListSource object, which can
31     * be written to support any data source
32     * (MySQL, Oracle, comma delimited file, xml, etc.)
33     *
34     * This base class MUST be extended by a child to
35     * actually render the list. The job of the DataList
36     * class is to provide the basic API and abstraction
37     * mechanism to handling searching, showing, sorting
38     * lists of data.
39     *
40     * Each column of data is associated with a title and a
41     * name. The title is what is shown to the user for that
42     * column. The name is the mapping between the column and
43     * the DataListSource. Each column can be marked
44     * as sortable and searchable. If a column is sortable,
45     * the title is a link that can be clicked on to sort.
46     * The sorting is done in the DataListSource object (
47     * via the sql query, or sort() functions depending on the
48     * data source itself)
49     *
50     * The DataList object will build the title, the search block
51     * (if any), the datalist controls (the links/imges for
52     * first, prev, next, last, all). Then the data columns/labels.
53     * Then it will fetch each of the rows of data to display
54     * from the DataListSource.
55     *
56     * The logic of the output calls follows in the order:
57     *
58     * title
59     * search table/block
60     * datalist controls (first, prev, next, last, all)
61     * data columns/labels
62     * data rows x through y
63     *
64     *
65     * REQUIREMENTS:
66     * You must use/define a DataListSource object.
67     * You MUST override/extend the following methods:
68     *
69     * * get_data_source() - used to set the DataListSource
70     * by this class.
71     * * user_setup() - used to set the columns to show and any
72     * options used by the DataList class and
73     * DataListSource object.
74     *
75     *
76     * UI ABSTRACTION METHODS
77     * These methods allow for some level of abstraction for
78     * the layout/look/feel of the actual list of data.
79     *
80     *
81     * * gui_init() - the function gives the child class a chance
82     * to do any building of the objects that will
83     * hold the search area, column headers and the
84     * rows of data.
85     *
86     * * child_build_column_header() - This method is responsible
87     * for building and inserting
88     * the column header title into
89     * the UI object.
90     *
91     * * child_add_row_cell() - This function is responsible for adding
92     * the cell in the current row. The method
93     * is responsible for keeping track of the
94     * location in its UI object for the current
95     * row.
96     *
97     * * child_get_gui() - This method returns the entire UI in 1 object
98     * or container. At this point the entire UI
99     * has been constructed, the entire list of data
100     * has been walked and inserted.
101     *
102     *
103     * @author Walter A. Boring IV <waboring@buildabetterweb.com>
104     * @package phpHtmlLib
105     */
106     class DataList extends BaseWidget {
107    
108     /**
109     * This value holds the number
110     * of pages of data we have
111     * to display.
112     *
113     */
114     var $_num_pages=1;
115    
116     /**
117     * The number of rows of data
118     * to show per "page".
119     * The default is 20.
120     *
121     */
122     var $_default_rows_per_page = 10;
123    
124     /**
125     * The max number of rows to
126     * show when the user does the
127     * "EXPAND" command.
128     */
129     var $_max_rows = 200;
130    
131    
132     /**
133     * Do we want to alternate the row colors?
134     * This helps to see each row easier.
135     */
136     var $alternating_row_colors = TRUE;
137    
138     /**
139     * prefix for all list variable
140     * names, so we can potentially
141     * have more then 1 list per page.
142     */
143     var $_global_prefix = '';
144    
145     /**
146     * The offset variable name
147     */
148     var $_offsetVar = "offset";
149    
150     /**
151     * The order by variable name
152     */
153     var $_orderbyVar = "orderby";
154    
155     /**
156     * Holds the db column name that
157     * we want to order by default.
158     */
159     var $_default_orderby = '';
160    
161     /**
162     * The reverseorder variable name
163     */
164     var $_reverseorderVar = "reverseorder";
165    
166     /**
167     * Holds a flag to let us know to
168     * reverse order the column by default
169     */
170     var $_default_reverseorder = "false";
171    
172     /**
173     * The number of rows variable name
174     */
175     var $_numrowsVar = "numrows";
176    
177     /**
178     * This var to tell us to show all
179     * data or not.
180     */
181     var $_showallVar = "showall";
182    
183     /**
184     * The search field variable
185     */
186     var $_search_fieldVar = "search_field";
187    
188     /**
189     * The search value
190     */
191     var $_search_valueVar = "search_value";
192    
193     /**
194     * The type of search
195     * advanced/simple
196     */
197     var $_search_typeVar = "search_type";
198    
199     /**
200     * The simple search modifier
201     * var name.
202     *
203     */
204     var $_simple_search_modifierVar = "simple_search_modifier";
205    
206    
207     /**
208     * Flag to let us know that search
209     * is enabled.
210     *
211     */
212     var $_search_flag = FALSE;
213    
214     /**
215     * Flag to let us know that
216     * advanced search is enabled
217     *
218     */
219     var $_advanced_search_flag = FALSE;
220    
221     /**
222     * Flag to enable simple search modifyer.
223     * IF enabled it will add a select that adds
224     * the "beings with", "contains" options for
225     * a simple search.
226     */
227     var $_simple_search_modifier = FALSE;
228    
229    
230     /**
231     * Holds the object block that is the
232     * search UI
233     */
234     var $_search_table = NULL;
235    
236     /**
237     * This holds a list of
238     * name=>value vars that the
239     * caller/child wants to propogate
240     * automatically.
241     *
242     */
243     var $_save_vars = array();
244    
245    
246     /**
247     * The column descriptions
248     * for the data we are working on
249     *
250     * @var array
251     */
252     var $_columns = array();
253    
254     /**
255     * Keeps track of the # of columns we have
256     */
257     var $_num_columns = 0;
258    
259    
260     /**
261     * This holds the form attributes
262     *
263     */
264     var $_form_attributes = array("method" => "GET",
265     "target" => "",
266     "action" => "",
267     "name" => "");
268    
269     /**
270     * Build everything inside a form?
271     *
272     */
273     var $_form_render_flag = FALSE;
274    
275    
276     /**
277     * flag to let us know if we want to show
278     * the results or not.
279     */
280     var $_show_results_flag = TRUE;
281    
282    
283     /**
284     * Holds our reference/copy of the
285     * DataListSource object which is used to
286     * access the data that this object uses
287     *
288     * @var DataListSource object
289     */
290     var $_datasource = NULL;
291    
292     /**
293     * This stores the base path to where the
294     * tool link images live. This lets you
295     * specify a new path to where your images
296     * live.
297     */
298 jonen 1.2 var $_image_path = "img/widgets";
299 jonen 1.3
300    
301 jonen 1.1
302     /**
303     * The constructor
304     *
305     * @param string - the title of the data list
306     * @param string - the overall width
307     * @param string - the column to use as the default sorting order
308     * @param boolean - sort the default column in reverse order?
309     */
310 jonen 1.3 function DataList($title, $width = "100%", $default_orderby='',
311     $default_reverseorder=FALSE ) {
312 jonen 1.1 $this->set_title( $title );
313     $this->set_form_name( str_replace(' ', '_', strtolower($title)) );
314     $this->set_width( $width );
315    
316     $this->_default_orderby = $default_orderby;
317     if ($default_reverseorder === TRUE) {
318     $default_reverseorder = "true";
319     } if ($default_reverse_order === FALSE) {
320     $default_reverseorder = "false";
321     }
322     $this->_default_reverseorder = $default_reverseorder;
323    
324     //Set the global prefix for our variables.
325     //want to make sure we can have multiple
326     //item lists per html page.
327     $this->set_global_prefix('');
328    
329     //child class MUST override this
330     //method to automatically set
331     //the DataListSource object.
332     //This class doesn't work without it.
333     $this->get_data_source();
334    
335     //Call the subclass setup function.
336     //This is a way to get around having
337     //to override the constructor and
338     //pass in the same params.
339     $this->user_setup();
340     }
341    
342     /**
343     * This function renders the final
344     * widget
345     *
346     */
347     function render($indent_level, $output_debug) {
348    
349     //setup the columns in their sorts
350     $this->setup_columns();
351    
352     //do any data prefetch work
353     //which may be child specific
354     if ($this->_show_results()) {
355     $this->data_prefetch();
356     }
357    
358     //This function gives the child class
359     //a chance to build the tables/divs/containers
360     //that will be responsible for the look/feel
361     //of the DataList
362     $this->gui_init();
363    
364     //see if we need to build the search area.
365     if ($this->is_search_enabled() || $this->is_advanced_search_enabled()) {
366     $this->_search_table = $this->child_build_search_table();
367     if ($this->_search_table) {
368     $this->set_form_render(TRUE);
369     }
370     }
371    
372    
373     if ($this->get_form_render()) {
374     $form = new FORMtag( array("method" => $this->get_form_method(),
375     "action" => $this->build_base_url(),
376     "name" => $this->get_form_name(),
377     "style" => "margin-top: 0px;margin-bottom:0px;") );
378    
379     $target = $this->get_form_target();
380     if ($target != NULL)
381     $form->set_tag_attribute("target",$target);
382    
383     $action = $this->get_form_action();
384     if ($action != NULL)
385     $form->set_tag_attribute("action",$action);
386    
387     //now build the UI and return it
388     $form->add( $this->build_gui() );
389    
390     //add the save vars the user wants.
391     $form->add( $this->_build_save_vars() );
392     } else {
393     $form = container();
394    
395     //now build the UI and return it
396     $form->add( $this->build_gui() );
397     }
398    
399     //add any javascript required
400     $container = container( $this->_javascript(), $form );
401     return $container->render( $indent_level, $output_debug );
402     }
403    
404     /**
405     * This function is responsible for calling the child
406     * class's methods for building the GUI container.
407     * This function builds the search area, the
408     * title, page controls, the column headers,
409     * and walks the rows of data and adds them
410     *
411     * A child class can override this method to
412     * move the placement of the search box
413     * relative to the data list. By default
414     * the search area comes above the table
415     * for the data list and page controls
416     *
417     * @return Container
418     */
419     function build_gui() {
420     $container = container();
421    
422     //if we have a search area to show
423     //add it to the ui.
424     if ($this->_search_table) {
425     $container->add( $this->_search_table );
426     }
427    
428     if ($this->_show_results()) {
429     //walk the list of columns and call the child
430     //method to add it
431     $column_count = count($this->_columns);
432     foreach( $this->_columns as $name => $col ) {
433     $this->child_build_column_header( $name, $col, $column_count);
434     }
435    
436     //now walk the list of rows and build and add the
437     //cells of data
438     $col_count = count($this->_columns);
439     while ($row = $this->_datasource->get_next_data_row()) {
440     $cnt = 1;
441     foreach( $this->_columns as $col_name => $data ) {
442     $obj = $this->build_column_item($row, $col_name);
443     if (!is_object($obj)) {
444     $obj = $this->_clean_string($obj, $col_name);
445     }
446     //
447 jonen 1.3 $this->child_add_row_cell($obj, $col_name, ($cnt == $col_count) ? TRUE : FALSE );
448 jonen 1.1 $cnt++;
449     }
450     }
451     $container->add( $this->child_get_gui() );
452     }
453    
454    
455     return $container;
456     }
457    
458     /**
459     * This function is called automatically by
460     * the DataList constructor. It must be
461     * extended by the child class to actually
462     * set the DataListSource object.
463     *
464     *
465     */
466     function get_data_source() {
467     user_error("DataList::get_data_source() - ".
468     "child class must override this to ".
469     "set the the DataListSource object.");
470     }
471    
472     /**
473     * A subclass can override this function
474     * to setup the class variables after
475     * the constructor. The constructor
476     * automatically calls this function.
477     *
478     */
479     function user_setup() {
480     user_error("DataList::user_setup() - ".
481     "child class must override this method ".
482     "to set the columns, and any options for ".
483     "the DataListSource.");
484     }
485    
486     /**
487     * A subclass can override this function
488     * to setup the class variables after
489     * the constructor. The constructor
490     * automatically calls this function.
491     *
492     */
493     function gui_init() {
494     user_error("DataList::gui_init() - ".
495     "child class must override this method ".
496     "to set up the containers/objects that will ".
497     "hold the search area, page controls, ".
498     "column headers and the data cells");
499     }
500    
501     /**
502     * This method is supposed to be written by
503     * the child class to build and add the column
504     * title to the UI
505     *
506     * @param string - the title of the column
507     * @param array - the column data ( from $this->_columns )
508     * @param int - the column #
509     *
510     */
511     function child_build_column_header($title, $col_data, $col_count) {
512     user_error("DataList::child_build_column_header() - ".
513     "child class must override this method ".
514     "to build the object that will be the ".
515     "individual column header/itle");
516     }
517    
518     /**
519     * This method is supposed to be written by
520     * the child class to add the cell data to the
521     * current row in the UI
522     *
523     * @param mixed - the object/string/entity that
524     * should get put into the column row cell.
525     * @param string - the name/title of the column that the
526     * object will live in
527     * @param boolean - flag that tells the function if this is
528     * is the last cell for the current row.
529     *
530     */
531     function child_add_row_cell($obj, $col_name, $last_in_row_flag) {
532     user_error("DataList::child_build_column_header() - ".
533     "child class must override this method ".
534     "to build the object that will be the ".
535     "individual column header/itle");
536     }
537    
538     /**
539     * This function is called after all of the data has
540     * been added to the UI object. It just returns the
541     * container that is the entire UI for the DataList
542     *
543     * @return Container
544     */
545     function child_get_gui() {
546     user_error("DataList::child_get_gui() - ".
547     "child class must override this method ".
548     "to return the wrapper that contains ".
549     "the entire UI.");
550     }
551    
552     /**
553     * This function builds the search
554     * block that lives above the results
555     *
556     * @return Container
557     */
558     function child_build_search_table() {
559     user_error("DataList::child_build_search_table() - ".
560     "child class must override this");
561     return NULL;
562     }
563    
564     /**
565     * This function provides a way to automatically
566     * add javascript to this object.
567     * This function is meant to be extended by the
568     * child class.
569     *
570     * @return SCRIPTtag object
571     */
572     function _javascript() {
573     return NULL;
574     }
575    
576     /**
577     * This function adds a header item to the column headers
578     * from a list of parameters.
579     *
580     * @param string - $label - the label to use for
581     * the column header.
582     * @param int - $size - the size for the table column.
583     * @param string - $dbfield - the db field associated
584     * with this label from the query.
585     * @param boolean - $sortable - flag to make this column sortable.
586     * @param boolean - $searchable - flag to make this column searchable.
587     * @param string - header align value.
588     * @param string - the maximum # of characters to allow in the cell.
589     *
590     * @return array a single header array
591     */
592     function add_header_item( $label, $size=100, $data_name=NULL,
593     $sortable=FALSE, $searchable=FALSE,
594     $align="left", $sortorder="",
595     $max_text_length=NULL) {
596    
597     $this->_columns[$label] = array("size" => $size,
598     "data_name" => $data_name,
599     "sortable" => $sortable,
600     "searchable" => $searchable,
601     "align" => $align,
602     "sortorder" => $sortorder,
603     "maxtextlength" => $max_text_length);
604     $this->_num_headers++;
605    
606     $this->_check_datasource("add_header_item");
607     $this->_datasource->add_column($label, $data_name, $sortable,
608     $searchable, $sortorder);
609     }
610    
611    
612     /**
613     * This function sets a prefix for all
614     * variables that are used in the item list
615     * table on a page. This allows you to have
616     * multiple itemlists on a single html page.
617     *
618     * @param string $prefix - the prefix for all vars.
619     */
620     function set_global_prefix($prefix) {
621     $this->_global_prefix = $prefix;
622     $this->_offsetVar = $prefix . "offset";
623     $this->_orderbyVar = $prefix . "orderby";
624     $this->_reverseorderVar = $prefix . "reverseorder";
625     $this->_numrowsVar = $prefix . "numrows";
626     $this->_showallVar = $prefix . "showall";
627     $this->_search_fieldVar = $prefix . "search_field";
628     $this->_search_valueVar = $prefix . "search_value";
629     $this->_search_typeVar = $prefix . $this->_search_typeVar;
630     $this->_simple_search_modifierVar = $prefix . $this->_simple_search_modifierVar;
631     }
632    
633     /**
634     * returns the current variable prefix
635     * string being used.
636     *
637     * @return string - current global prefix
638     */
639     function get_global_prefix() {
640     return $this->_global_prefix;
641     }
642    
643     /**
644     * This function is used to set the
645     * DataListSource object for this instance
646     *
647     * @param DataListSource object
648     */
649     function set_data_source( $datasource ) {
650     $this->_datasource = &$datasource;
651     }
652    
653     /**
654     * Enable the search ability.
655     *
656     * @param boolean
657     */
658     function search_enable( ) {
659     $this->_search_flag = TRUE;
660     if (!$this->is_advanced_search_enabled()) {
661     $this->set_search_type("simple");
662     }
663     }
664    
665     /**
666     * Disable the search ability.
667     *
668     * @param boolean
669     */
670     function search_disable( ) {
671     $this->_search_flag = FALSE;
672     }
673    
674     /**
675     * get the status of the search
676     * ability.
677     *
678     * @return boolean
679     */
680     function is_search_enabled() {
681     return $this->_search_flag;
682     }
683    
684    
685     /**
686     * Enable the advanced search
687     * capability
688     * NOTE: Child class MUST
689     * extend the
690     * _build_advanced_search_table
691     */
692     function advanced_search_enable() {
693     $this->_advanced_search_flag = TRUE;
694     if (!$this->is_search_enabled()) {
695     $this->set_search_type("advanced");
696     }
697     }
698    
699     /**
700     * Disable the advanced search
701     * capability
702     *
703     */
704     function advanced_search_disable() {
705     $this->_advanced_search_flag = FALSE;
706     }
707    
708     /**
709     * This returns the status of the
710     * advanced search flag.
711     *
712     * @return boolean
713     */
714     function is_advanced_search_enabled() {
715     return $this->_advanced_search_flag;
716     }
717    
718     /**
719     * Set the simple search modifyer
720     * flag.
721     * NOTE: by default all the modifiers
722     * are enabled. You can limit the
723     * modifiers by passing in the
724     * string of defines of which ones
725     * you want enabled.
726     *
727     * MODIFIERS:
728     * SEARCH_BEGINS_WITH
729     * SEARCH_CONTAINS
730     * SEARCH_EXACT
731     * SEARCH_ENDS_WITH
732     *
733     * ie. SEARCH_BEGINS_WITH.SEARCH_EXACT
734     * will enable ONLY the
735     * "begins with" and "exact" modifiers.
736     *
737     * @param string
738     */
739     function set_simple_search_modifier( $modifier = SEARCH_ALL ) {
740     if ($modifier == 0) {
741     $this->_simple_search_modifier = SEARCH_BEGINS_WITH |
742     SEARCH_CONTAINS |
743     SEARCH_EXACT |
744     SEARCH_ENDS_WITH;
745     } else {
746     $this->_simple_search_modifier = $modifier;
747     }
748     }
749    
750     /**
751     * gets the value of the search modifier
752     * flag.
753     */
754     function get_simple_search_modifier() {
755     return $this->_simple_search_modifier;
756     }
757    
758     /**
759     * This function sets the default # of rows
760     * per page to display. By default its 10.
761     * This lets the user override this value.
762     *
763     * @param int - the # of rows to use.
764     */
765     function set_default_num_rows( $num_rows ) {
766     $this->default_rows_per_page = $num_rows;
767     }
768    
769     /**
770     * This function gets the current default
771     * number of rows to display setting.
772     *
773     * @return int
774     */
775     function get_default_num_rows( ) {
776     return $this->_default_rows_per_page;
777     }
778    
779    
780     /**
781     * This function sets the save variables
782     * that the user/child wants to automatically
783     * propogate
784     *
785     * @param array - name=>value pairs of the data
786     * that they want to propogate
787     */
788     function set_save_vars( $vars ) {
789     $this->_save_vars = $vars;
790     }
791    
792     /**
793     * This returns the Maximum # of rows to
794     * display when in expand mode
795     *
796     * @return int
797     */
798     function get_max_rows() {
799     return $this->_max_rows;
800     }
801    
802     /**
803     * This sets the maximum # of rows to
804     * display when in expand mode
805     *
806     * @param int - new # of maximum rows
807     * to display when in 'expand' mode
808     *
809     */
810     function set_max_rows( $max ) {
811     $this->_max_rows = $max;
812     }
813    
814    
815    
816     /**
817     * This function is used to set up any
818     * data that needs to be munged before the
819     * data is fetched from the DataListSource
820     *
821     */
822     function data_prefetch() {
823     $this->_check_datasource("data_prefetch");
824    
825     if ($this->showall()) {
826     $this->set_default_num_rows( $this->get_max_rows() );
827     $this->set_numrows( $this->get_max_rows() );
828     }
829    
830     $limit = $this->numrows();
831     $this->_datasource->query($this->offset(), $limit,
832     $this->orderby(), $this->reverseorder(),
833     $this->search_field(), $this->search_value(),
834     $this->simple_search_modifier_value(),
835     $this->search_type() );
836     }
837    
838    
839    
840     /*
841     * Takes an array of (name, sortable, db_field, alignment,
842     * size), with one element corresponding to each column.
843     */
844     function setup_columns() {
845     $temp_headers = array();
846    
847     foreach( $this->_columns as $col_name => $data ) {
848     if ($data["sortorder"] == "reverse") {
849     $data["reverseorder"] = "true";
850     }
851     else {
852     $data["reverseorder"] = "false";
853     }
854     $temp_headers[$col_name] = $data;
855     }
856     $this->_columns = $temp_headers;
857     }
858    
859    
860    
861     /**
862     * general DataListSource object checker.
863     *
864     */
865     function _check_datasource($function_name) {
866     if (!is_object($this->_datasource)) {
867     user_error("DataList::".$function_name."() - DataListSource object is not set");
868     exit;
869     }
870     }
871    
872    
873     /*********************************************/
874     /* REQUEST VARIABLE SECTION */
875     /*********************************************/
876    
877     /**
878     * This function returns the current value
879     * of the offset variable. This is an offset
880     * into the query return data set.
881     *
882     * @return int - the current value.
883     */
884     function offset() {
885     if (!$_REQUEST[$this->_offsetVar]) {
886     $this->set_offset(0);
887     }
888     return (int)$_REQUEST[$this->_offsetVar];
889     }
890    
891     /**
892     * This function is used to set/change
893     * the offset for this list.
894     *
895     * @param int - the new offset.
896     */
897     function set_offset($new_offset) {
898     $_REQUEST[$this->_offsetVar] = $new_offset;
899     }
900    
901     /**
902     * This function returns the value of the
903     * current orderby variable.
904     *
905     * @return string.
906     */
907     function orderby() {
908     if (!$_REQUEST[$this->_orderbyVar]) {
909     $_REQUEST[$this->_orderbyVar] = $this->_default_orderby;
910     }
911    
912     return $_REQUEST[$this->_orderbyVar];
913     }
914    
915     /**
916     * This builds a query string var for the
917     * orderby value.
918     *
919     * @return string - "orderby=(thevalue)"
920     */
921     function build_orderby_querystring() {
922     $str = $this->_orderbyVar."=".$this->orderby();
923     return $str;
924     }
925    
926     /**
927     * This function returns the current value of
928     * the reverse order member variable.
929     *
930     * @return string.
931     */
932     function reverseorder() {
933     if (!$_REQUEST[$this->_reverseorderVar]) {
934     $this->set_reverseorder($this->_default_reverseorder);
935     }
936     return $_REQUEST[$this->_reverseorderVar];
937     }
938    
939     /**
940     * This function sets the reverse order flag
941     * to a new value.
942     *
943     * @param string - the new value.
944     */
945     function set_reverseorder($new_value) {
946     $_REQUEST[$this->_reverseorderVar] = $new_value;
947     }
948    
949     /**
950     * This builds a query string var for the
951     * reverseorder value.
952     *
953     * @return string - "orderby=(thevalue)"
954     */
955     function build_reverseorder_querystring() {
956     $str = $this->_reverseorderVar."=".$this->reverseorder();
957     return $str;
958     }
959    
960     /**
961     * This function returns the number of rows
962     * that the query found.
963     *
964     * @return int - the number of rows
965     */
966     function numrows() {
967     if (!$_REQUEST[$this->_numrowsVar]) {
968     $this->set_numrows($this->_default_rows_per_page);
969     }
970     return (int) $_REQUEST[$this->_numrowsVar];
971     }
972    
973     /**
974     * This function sets the # of rows to display
975     * per page.
976     *
977     * @param int - the # of rows
978     */
979     function set_numrows($new_numrows) {
980     $_REQUEST[$this->_numrowsVar] = $new_numrows;
981     }
982    
983     /**
984     * returns the current value of
985     * the search field name
986     *
987     * @return string
988     */
989     function search_field() {
990     if (!$_REQUEST[$this->_search_fieldVar]) {
991     $_REQUEST[$this->_search_fieldVar] = '';
992     }
993     return $_REQUEST[$this->_search_fieldVar];
994     }
995    
996     /**
997     * This builds a query string var for the
998     * searchfield value.
999     *
1000     * @return string - "orderby=(thevalue)"
1001     */
1002     function build_searchfield_querystring() {
1003     $str = $this->_search_fieldVar."=".$this->searchfield();
1004     return $str;
1005     }
1006    
1007     /**
1008     * returns the current value of
1009     * te search field value.
1010     *
1011     * @return string
1012     */
1013     function search_value() {
1014     if (!$_REQUEST[$this->_search_valueVar]) {
1015     $_REQUEST[$this->_search_valueVar] = '';
1016     }
1017     return $_REQUEST[$this->_search_valueVar];
1018     }
1019    
1020     /**
1021     * This builds a query string var for the
1022     * searchfield value.
1023     *
1024     * @return string - "orderby=(thevalue)"
1025     */
1026     function build_searchvalue_querystring() {
1027     $str = $this->_search_valueVar."=".$this->search_value();
1028     return $str;
1029     }
1030    
1031     /**
1032     * returns the current value of the
1033     * simple search modifier
1034     *
1035     * @return string
1036     */
1037     function simple_search_modifier_value() {
1038     if (!$_REQUEST[$this->_simple_search_modifierVar]) {
1039     $_REQUEST[$this->_simple_search_modifierVar] = '';
1040     }
1041     return $_REQUEST[$this->_simple_search_modifierVar];
1042     }
1043    
1044    
1045     /**
1046     * returns the type of search being used
1047     *
1048     * @return string
1049     */
1050     function search_type() {
1051     if (!$_REQUEST[$this->_search_typeVar]) {
1052     $_REQUEST[$this->_search_typeVar] = "simple";
1053     }
1054     return $_REQUEST[$this->_search_typeVar];
1055     }
1056    
1057     /**
1058     * This function sets the search type
1059     *
1060     * @param string - the search type
1061     * "simple" or "advanced"
1062     */
1063     function set_search_type($type) {
1064     $_REQUEST[$this->_search_typeVar] = $type;
1065     }
1066    
1067    
1068     /**
1069     * returns the current value of the showall
1070     * flag. This tells us if they want the entire
1071     * list of data back from the DB.
1072     *
1073     * @return string - the current value
1074     */
1075     function showall() {
1076     if (!$_REQUEST[$this->_showallVar]) {
1077     $_REQUEST[$this->_showallVar] = 0;
1078     }
1079     return (int) $_REQUEST[$this->_showallVar];
1080     }
1081    
1082    
1083    
1084     /*******************************************/
1085     /* FORM VARIABLES SECTION */
1086     /*******************************************/
1087    
1088     /**
1089     * This function is used to set the
1090     * form name
1091     *
1092     * @param string
1093     */
1094     function set_form_name($name) {
1095     $this->_form_attributes["name"] = $name;
1096     }
1097    
1098     /**
1099     * This function is used to get
1100     * the form name
1101     *
1102     * @return string
1103     */
1104     function get_form_name() {
1105     return $this->_form_attributes["name"];
1106     }
1107    
1108     /**
1109     * This function is used to set the
1110     * form target
1111     *
1112     * @param string
1113     */
1114     function set_form_target($target) {
1115     $this->_form_attributes["target"] = $target;
1116     }
1117    
1118     /**
1119     * This function is used to get
1120     * the form target
1121     *
1122     * @return string
1123     */
1124     function get_form_target() {
1125     return $this->_form_attributes["target"];
1126     }
1127    
1128     /**
1129     * This function is used to set the
1130     * form method
1131     *
1132     * @param string (POST or GET)
1133     */
1134     function set_form_method($method) {
1135     if ($method != "GET" && $method != "POST") {
1136     user_error("DataList::set_form_method() - INVALID Form method ".$method);
1137     } else {
1138     $this->_form_attributes["method"] = $method;
1139     }
1140     }
1141    
1142     /**
1143     * This function is used to get
1144     * the form method
1145     *
1146     * @return string (POST or GET)
1147     */
1148     function get_form_method() {
1149     return $this->_form_attributes["method"];
1150     }
1151    
1152     /**
1153     * Sets the form action
1154     *
1155     * @param string
1156     */
1157     function set_form_action($action) {
1158     $this->_form_attributes["action"] = $action;
1159     }
1160    
1161     /**
1162     * This function is used to get
1163     * the form action
1164     *
1165     * @return string (POST or GET)
1166     */
1167     function get_form_action() {
1168     return $this->_form_attributes["action"];
1169     }
1170    
1171     /**
1172     * Sets whether to the output into a form
1173     *
1174     * @param bool
1175     */
1176     function set_form_render($flag) {
1177     $this->_form_render_flag = $flag;
1178     }
1179    
1180     /**
1181     * Return the state of the form render
1182     *
1183     * @return bool
1184     */
1185     function get_form_render() {
1186     return $this->_form_render_flag;
1187     }
1188    
1189     /**
1190     * This function is used to set the
1191     * message displayed when no data is found
1192     *
1193     * @param string
1194     */
1195     function set_not_found_message($mesg) {
1196     $this->_check_datasource("set_not_found_message");
1197     $this->_datasource->set_not_found_message($mesg);
1198     }
1199    
1200    
1201     /**
1202     * This function is used to set the value
1203     * of the _show_results_flag
1204     *
1205     * @param boolean - TRUE to show the results
1206     */
1207     function set_show_results( $flag=TRUE ) {
1208     $this->_show_results_flag = $flag;
1209     }
1210    
1211    
1212     /**
1213     * This function is used to let render() know
1214     * that we should show the results or not.
1215     *
1216     * @return boolean
1217     */
1218     function _show_results() {
1219     return $this->_show_results_flag;
1220     }
1221    
1222     /**
1223     * this method builds some hidden
1224     * form fields to automatically
1225     * be placed inside the form.
1226     *
1227     * @return ContainerWidget object.
1228     */
1229     function _build_save_vars() {
1230     $container = container();
1231     foreach($this->_save_vars as $name => $value) {
1232     $container->add(form_hidden($name, $value));
1233     }
1234     return $container;
1235     }
1236    
1237     /**
1238     * This function sets the save variables
1239     * that the user/child wants to automatically
1240     * propogate
1241     *
1242     * @param array - name=>value pairs of the data
1243     * that they want to propogate
1244     */
1245     function set_save_vars($vars) {
1246     $this->_save_vars = $vars;
1247     }
1248    
1249     /**
1250     * This builds the base url used
1251     * by the column headers as well
1252     * as the page tool links.
1253     *
1254     * it basically builds:
1255     * $_SELF?$_GET
1256     *
1257     * @return string
1258     */
1259     function build_base_url() {
1260    
1261     $url = $_SERVER["PHP_SELF"]."?";
1262    
1263     if ($this->get_form_method() == "POST") {
1264     return $url;
1265     }
1266    
1267     $vars = array_merge($_POST, $_GET);
1268     //request method independant access to
1269     //browser variables
1270     if (count($vars)) {
1271     //walk through all of the get vars
1272     //and add them to the url to save them.
1273     foreach($vars as $name => $value) {
1274    
1275     if ($name != $this->_offsetVar &&
1276     $name != $this->_orderbyVar &&
1277     $name != $this->_reverseorderVar &&
1278     $name != $this->_search_valueVar
1279     ) {
1280     if (is_array($value)) {
1281     $url .= $name."[]=".implode("&".$name."[]=",$value)."&";
1282     } else {
1283     $url .= $name."=".urlencode(stripslashes($value))."&";
1284     }
1285     }
1286     }
1287     }
1288    
1289     return $url;
1290     }
1291    
1292     /**
1293     * This function builds the 'tool' images that
1294     * allow you to walk through the data list itself.
1295     * It provides image links for
1296     * first - go to the first page in the data list
1297     * prev - go to the previous page in the data list
1298     * next - go to the next page in the data list
1299     * last - go to the last page in the data list
1300     * all - show the rest of the list from the current offset
1301     *
1302     * @param string - which tool image to build
1303     * @return Object
1304     */
1305     function build_tool_link( $which ) {
1306     $num_pages = $this->get_num_pages();
1307     $cur_page = $this->get_current_page();
1308     $last_page = $this->get_last_page();
1309    
1310     $image_path = $this->get_image_path();
1311     switch ($which) {
1312    
1313     case "first":
1314     $rows_string = "First ".$this->get_default_num_rows()." Rows";
1315     if ($this->offset() <= 0) {
1316     $obj = html_img($image_path."/first_group_button_inactive.gif",
1317     '','',0,$rows_string, NULL, $rows_string);
1318     } else {
1319     $url = $this->_build_tool_url(0);
1320     $obj = html_img_href($url, $image_path."/first_group_button.gif",
1321     '','',0, $rows_string, NULL, NULL, $rows_string);
1322     }
1323     break;
1324    
1325     case "prev":
1326     $rows_string = "Previous ".$this->get_default_num_rows()." Rows";
1327     if ($this->offset() <= 0) {
1328     $obj = html_img($image_path."/prev_group_button_inactive.gif",
1329     '','',0,$rows_string, NULL, $rows_string);
1330     } else {
1331     $offset = $this->offset() - $this->numrows();
1332     if ($offset < 0) {
1333     $offset = 0;
1334     }
1335     $url = $this->_build_tool_url($offset);
1336     $obj = html_img_href($url, $image_path."/prev_group_button.gif",
1337     '','',0, $rows_string, NULL, NULL, $rows_string);
1338     }
1339     break;
1340    
1341     case "next":
1342     $rows_string = "Next ".$this->get_default_num_rows()." Rows";
1343     if (($num_pages == 1) || ($cur_page == $last_page)) {
1344     $obj = html_img($image_path."/next_group_button_inactive.gif",
1345     '','',0, $rows_string, NULL, $rows_string);
1346     } else {
1347     $offset = $this->offset() + $this->numrows();
1348     $url = $this->_build_tool_url($offset);
1349     $obj = html_img_href($url, $image_path."/next_group_button.gif",
1350     '','',0, $rows_string, NULL, NULL, $rows_string);
1351     }
1352     break;
1353    
1354     case "last":
1355     $rows_string = "Last ".$this->get_default_num_rows()." Rows";
1356     if (($num_pages == 1) || ($cur_page == $last_page)) {
1357     $obj = html_img($image_path."/last_group_button_inactive.gif",
1358     '','',0, $rows_string, NULL, $rows_string);
1359     } else {
1360     $offset = (int)(($num_pages - 1) * $this->numrows());
1361     $url = $this->_build_tool_url($offset);
1362     $obj = html_img_href($url, $image_path."/last_group_button.gif",
1363     '','',0, $rows_string, NULL, NULL, $rows_string);
1364     }
1365     break;
1366    
1367     case "all":
1368     $offset = $this->offset();
1369     if ($this->showall()) {
1370     $url = $this->_build_tool_url($offset, TRUE, 0);
1371     $obj = html_img_href($url, $image_path."/close_group_button.gif",
1372     '','',0,"Collapse Rows", NULL, NULL, "Collapse Rows");
1373     } else {
1374     if (($num_pages == 1)) {
1375     $obj = html_img($image_path."/expand_group_button_inactive.gif",
1376     '','',0, "Expand Rows", NULL, "Expand Rows");
1377     } else {
1378     $url = $this->_build_tool_url($offset, TRUE, 1);
1379     $obj = html_img_href($url, $image_path."/expand_group_button.gif",
1380     '','',0,"Expand Rows", NULL, NULL, "Expand Rows");
1381     }
1382     }
1383     //so we don't save it into the mozilla navigation bar links
1384     unset($url);
1385     break;
1386     }
1387    
1388     if ($url) {
1389     $this->_save_mozilla_nav_link($which, $url);
1390     }
1391    
1392     return $obj;
1393     }
1394    
1395     /**
1396     * This function is used to build the url
1397     * for a tool link.
1398     * (first, prev, next, last, all)
1399     *
1400     * @param int - the offset for the link
1401     * @param boolean - add the showall value to the url
1402     * @param int - the showall value to use if the flag is on
1403     *
1404     * @return string
1405     */
1406     function _build_tool_url($offset, $showall_flag=FALSE, $showall_value=0) {
1407     if ($this->get_form_method() == "POST") {
1408     $form_name = $this->get_form_name();
1409     $url = "javascript: document.".$form_name;
1410     $url .= ".".$this->_offsetVar.".value='".$offset."';";
1411    
1412     //add the showall variable to the post
1413     if ($showall_flag) {
1414     $form_field = $this->_showallVar;
1415     $url .= "document.".$form_name.".";
1416     $url .= $form_field.".value='".$showall_value."';";
1417     }
1418    
1419     $url .= "document.".$form_name.".submit();";
1420     } else {
1421     $url = $this->build_base_url();
1422     $url .= $this->build_state_vars_query_string($offset, $showall_flag,
1423     $showall_value);
1424     }
1425     return $url;
1426     }
1427    
1428     /**
1429     * this function is used to build a sub query string
1430     * of all of the query string vars to save the
1431     * state of the DBItemList. This is used for pages
1432     * that want to come back to the list at the same state
1433     *
1434     * @return string - name=value& pairs
1435     */
1436     function build_state_vars_query_string($offset, $showall_flag=FALSE,
1437     $showall_value=0) {
1438     $str = "";
1439    
1440     $str .= $this->_offsetVar."=".urlencode($offset);
1441     $str .= "&".$this->_orderbyVar."=".urlencode($this->orderby());
1442     $str .= "&".$this->_reverseorderVar."=".urlencode($this->reverseorder());
1443     $str .= "&".$this->_search_fieldVar."=".urlencode($this->search_field());
1444     $str .= "&".$this->_search_valueVar."=".urlencode($this->search_value());
1445     $str .= "&".$this->_simple_search_modifierVar."=".urlencode($this->simple_search_modifier_value());
1446     $str .= "&".$this->_search_typeVar."=".urlencode($this->search_type());
1447     if ($showall_flag) {
1448     $str .= "&".$this->_showallVar."=".urlencode($showall_value);
1449     }
1450    
1451     return $str;
1452     }
1453    
1454     /**
1455     * This function stores the url for each of the tool
1456     * urls, so we can push these out for mozilla.
1457     * Mozilla has a nice navigation bar feature that
1458     * lets you program first, prev, next, last links
1459     *
1460     * @param string - which tool link
1461     * @param string - the url for that link
1462     */
1463     function _save_mozilla_nav_link($which, $url) {
1464     $this->_mozilla_nav_links[$which] = $url;
1465     }
1466    
1467    
1468     /**
1469     * This function returns the path to the
1470     * images used in this class
1471     *
1472     * @return string
1473     */
1474     function get_image_path() {
1475     return $this->_image_path;
1476     }
1477    
1478     /**
1479     * This function returns the path to the
1480     * images used in this class
1481     *
1482     * @return string
1483     */
1484     function set_image_path($path) {
1485     return $this->_image_path = $path;
1486     }
1487    
1488     /**
1489     * This function returns the current
1490     * page that the item list is on.
1491     *
1492     * @return int
1493     */
1494     function get_current_page() {
1495     return((int) ($this->offset() / $this->numrows())) + 1;
1496     }
1497    
1498     /**
1499     * This function returns the #
1500     * of pages that are available
1501     * for this list of items.
1502     *
1503     * @return int
1504     */
1505     function get_num_pages() {
1506     $this->_check_datasource("get_num_pages");
1507     $total_rows = $this->_datasource->get_total_rows();
1508    
1509     $cnt = (int)($total_rows / $this->numrows());
1510     if ((($total_rows % $this->numrows()) != 0) || ($total_rows == 0)) {
1511     $cnt++;
1512     }
1513     return $cnt;
1514     }
1515    
1516     /**
1517     * This calculates the last page #
1518     * for this list of items
1519     *
1520     * @return int
1521     */
1522     function get_last_page() {
1523     return $this->get_num_pages();
1524     }
1525    
1526     /**
1527     * This function builds the string
1528     * that describes the current page
1529     * out of n pages the list is showing
1530     *
1531     * @return string (ie. 1 to 10 of 25)
1532     */
1533     function get_page_info() {
1534     $cur_page = $this->get_current_page();
1535     $low_range = $this->offset() + 1;
1536     $num_pages = $this->get_num_pages();
1537     $num_rows_per_page = $this->numrows();
1538    
1539     $this->_check_datasource("get_page_info");
1540     $total_rows = $this->_datasource->get_total_rows();
1541    
1542     $high_range = $low_range + ($num_rows_per_page - 1);
1543     if ($high_range > $total_rows) {
1544     $high_range = $total_rows;
1545     }
1546    
1547     if ($total_rows == 0) {
1548     $str = "0 of 0";
1549     } else {
1550     $str = $low_range . " to ". $high_range;
1551     $str .= " of ".$total_rows;
1552     }
1553    
1554     return $str;
1555     }
1556    
1557    
1558    
1559     /**
1560     * This builds a url for a particular
1561     * column header.
1562     *
1563     * @param string - $col_name
1564     * @return Atag object;
1565     */
1566     function build_column_url($col_name) {
1567     $orderby = $this->orderby();
1568     $reverseorder = $this->reverseorder();
1569     $search_value = $this->search_value();
1570    
1571     $order_value = $this->_columns[$col_name]["data_name"];
1572     $reverse_value = "false";
1573     if (!$reverseorder) {
1574     $reverseorder = 'false';
1575     }
1576    
1577     if ($orderby == $order_value && $reverseorder === 'false') {
1578     $reverse_value = "true";
1579     }
1580    
1581     if ($this->form_method == "POST") {
1582     //we have to construct this url
1583     //specially.
1584     $form_name = $this->get_form_name();
1585    
1586     $url = "javascript: ";
1587     //set the offset correctly
1588     $url .= "document.".$form_name.".".$this->_offsetVar.".value='".$this->offset()."';";
1589     //set the orderby correctly.
1590     $url .= "document.".$form_name.".".$this->_orderbyVar.".value='".$order_value."';";
1591     //set the reverseorder
1592     $url .= "document.".$form_name.".".$this->_reverseorderVar.".value='".$reverse_value."';";
1593    
1594     $url .= "document.".$form_name.".submit();";
1595     } else {
1596     //handle the normal get.
1597     $url = $this->build_base_url();
1598     //Now add the orderby, reverseorder and offset vars
1599     $url .= $this->_offsetVar ."=0&";
1600     //set the orderbyvar
1601     $url .= $this->_orderbyVar ."=".$order_value."&";
1602     //set the reverseorder
1603     $url .= $this->_reverseorderVar ."=".$reverse_value."&";
1604     //set the search value
1605     $url .= $this->_search_valueVar ."=".$search_value;
1606     }
1607    
1608     return $url;
1609     }
1610    
1611     /**
1612     * This is the basic function for letting us
1613     * do a mapping between the column name in
1614     * the header, to the value found in the DB.
1615     *
1616     * NOTE: this function is meant to be overridden
1617     * so that you can push whatever you want.
1618     *
1619     * @param array - $row_data - the entire data for the row
1620     * @param string - $col_name - the name of the column header
1621     * for this row to render.
1622     * @return mixed - either a HTMLTag object, or raw text.
1623     */
1624     function build_column_item($row_data, $col_name) {
1625     $key = $this->_columns[$col_name]["data_name"];
1626    
1627     if ($row_data[$key] == '') {
1628     return "&nbsp;";
1629     } else {
1630     return $this->filter_column_string($row_data[$key]);
1631     }
1632     }
1633    
1634    
1635     /**
1636     * This does some magic filtering on the data
1637     * that we display in a column. This helps
1638     * to prevent nast data that may have html
1639     * tags in it.
1640     *
1641     * @param string - the column data u want to filter
1642     * @return string the cleaned/filtered data
1643     */
1644     function filter_column_string($data) {
1645 jonen 1.3 // WAS: return htmlspecialchars(trim($data));
1646    
1647     // NEW: require 'flib/Application/i18n/TextEncode.php'
1648     // this will do a 'htmlentities' RECURSIVE on each item
1649 joko 1.4 $encoder = new Data_Encode($data);
1650 jonen 1.3 $encoder->toHTML();
1651     return $data;
1652 jonen 1.1 }
1653    
1654    
1655    
1656     /**
1657     * This function is used to make sure that the string we are
1658     * placing in a cell has been "cleaned"
1659     *
1660     * @param mixed - the cell object. It can be a string.
1661     * @param string - the name of the column this object/string
1662     * will live
1663     *
1664     * @return mixed - the cleaned string or object
1665     */
1666     function _clean_string($obj, $col_name){
1667     if (is_string($obj)) {
1668     if ($this->_columns[$col_name]["maxtextlength"]) {
1669     //looks like we need to make sure we
1670     //truncate the string to a max length
1671     if (strlen($obj) > $this->_columns[$col_name]["maxtextlength"]) {
1672     //we need to truncate it.
1673     $obj = substr($obj, 0, $this->_columns[$col_name]["maxtextlength"]);
1674     $obj .= "...";
1675     }
1676     }
1677     }
1678     return $obj;
1679     }
1680    
1681     /********************************/
1682     /* SEARCH RELATED */
1683     /********************************/
1684    
1685     /**
1686     * This method gets the array of
1687     * searchable header fields (columns)
1688     *
1689     * @return array
1690     */
1691     function _get_searchable_fields() {
1692     $fields = array();
1693     foreach($this->_columns as $name => $header) {
1694     if ($header["searchable"] == TRUE) {
1695     $fields[$name] = $header["data_name"];
1696     }
1697     }
1698     return $fields;
1699     }
1700    
1701     /**
1702     * This builds the simple search modifier
1703     * select box.
1704     *
1705     * @return INPUTtag object.
1706     */
1707     function _build_simple_search_modifier() {
1708    
1709     $options = array();
1710    
1711     $modifier = $this->get_simple_search_modifier();
1712    
1713     if ($modifier & SEARCH_BEGINS_WITH) {
1714     $options["beginning with"] = "BEGINS";
1715     }
1716     if ($modifier & SEARCH_CONTAINS) {
1717     $options["containing"] = "CONTAINS";
1718     }
1719     if ($modifier & SEARCH_EXACT) {
1720     $options["matching"] = "EXACT";
1721     }
1722     if ($modifier & SEARCH_ENDS_WITH) {
1723     $options["ending with"] = "ENDS";
1724     }
1725    
1726     $selected = $this->simple_search_modifier_value();
1727     //make the default Begins with
1728     if (!$selected) {
1729     $selected = "BEGINS";
1730     }
1731    
1732     return form_select($this->_simple_search_modifierVar, $options, $selected);
1733     }
1734    
1735     /**
1736     * This function is used to make safe
1737     * any query string value that is used
1738     *
1739     * @param string
1740     * @return string
1741     */
1742     function search_value_filter( $value ) {
1743     return stripslashes( trim($value) );
1744     }
1745     }
1746     ?>

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed