Subversion Repositories Applications.papyrus

Rev

Rev 320 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
320 jpm 1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4: */
3
// +----------------------------------------------------------------------+
4
// | PHP version 4.0                                                      |
5
// +----------------------------------------------------------------------+
6
// | Copyright (c) 1997-2003 The PHP Group                                |
7
// +----------------------------------------------------------------------+
8
// | This source file is subject to version 2.0 of the PHP license,       |
9
// | that is bundled with this package in the file LICENSE, and is        |
10
// | available at through the world-wide-web at                           |
11
// | http://www.php.net/license/2_02.txt.                                 |
12
// | If you did not receive a copy of the PHP license and are unable to   |
13
// | obtain it through the world-wide-web, please send a note to          |
14
// | license@php.net so we can mail you a copy immediately.               |
15
// +----------------------------------------------------------------------+
16
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com>                        |
17
// |          Bertrand Mansion <bmansion@mamasam.com>                     |
18
// +----------------------------------------------------------------------+
19
//
443 ddelon 20
// $Id: select.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $
320 jpm 21
 
22
require_once('HTML/QuickForm/element.php');
23
 
24
/**
25
 * Class to dynamically create an HTML SELECT
26
 *
27
 * @author       Adam Daniel <adaniel1@eesus.jnj.com>
28
 * @author       Bertrand Mansion <bmansion@mamasam.com>
29
 * @version      1.0
30
 * @since        PHP4.04pl1
31
 * @access       public
32
 */
33
class HTML_QuickForm_select extends HTML_QuickForm_element {
34
 
35
    // {{{ properties
36
 
37
    /**
38
     * Contains the select options
39
     *
40
     * @var       array
41
     * @since     1.0
42
     * @access    private
43
     */
44
    var $_options = array();
45
 
46
    /**
47
     * Default values of the SELECT
48
     *
49
     * @var       string
50
     * @since     1.0
51
     * @access    private
52
     */
53
    var $_values = null;
54
 
55
    // }}}
56
    // {{{ constructor
57
 
58
    /**
59
     * Class constructor
60
     *
61
     * @param     string    Select name attribute
62
     * @param     mixed     Label(s) for the select
63
     * @param     mixed     Data to be used to populate options
64
     * @param     mixed     Either a typical HTML attribute string or an associative array
65
     * @since     1.0
66
     * @access    public
67
     * @return    void
68
     */
69
    function HTML_QuickForm_select($elementName=null, $elementLabel=null, $options=null, $attributes=null)
70
    {
71
        HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
72
        $this->_persistantFreeze = true;
73
        $this->_type = 'select';
74
        if (isset($options)) {
75
            $this->load($options);
76
        }
77
    } //end constructor
78
 
79
    // }}}
80
    // {{{ apiVersion()
81
 
82
    /**
83
     * Returns the current API version
84
     *
85
     * @since     1.0
86
     * @access    public
87
     * @return    double
88
     */
89
    function apiVersion()
90
    {
91
        return 2.3;
92
    } //end func apiVersion
93
 
94
    // }}}
95
    // {{{ setSelected()
96
 
97
    /**
98
     * Sets the default values of the select box
99
     *
100
     * @param     mixed    $values  Array or comma delimited string of selected values
101
     * @since     1.0
102
     * @access    public
103
     * @return    void
104
     */
105
    function setSelected($values)
106
    {
107
        if (is_string($values) && $this->getMultiple()) {
108
            $values = split("[ ]?,[ ]?", $values);
109
        }
110
        if (is_array($values)) {
111
            $this->_values = array_values($values);
112
        } else {
113
            $this->_values = array($values);
114
        }
115
    } //end func setSelected
116
 
117
    // }}}
118
    // {{{ getSelected()
119
 
120
    /**
121
     * Returns an array of the selected values
122
     *
123
     * @since     1.0
124
     * @access    public
125
     * @return    array of selected values
126
     */
127
    function getSelected()
128
    {
129
        return $this->_values;
130
    } // end func getSelected
131
 
132
    // }}}
133
    // {{{ setName()
134
 
135
    /**
136
     * Sets the input field name
137
     *
138
     * @param     string    $name   Input field name attribute
139
     * @since     1.0
140
     * @access    public
141
     * @return    void
142
     */
143
    function setName($name)
144
    {
145
        $this->updateAttributes(array('name' => $name));
146
    } //end func setName
147
 
148
    // }}}
149
    // {{{ getName()
150
 
151
    /**
152
     * Returns the element name
153
     *
154
     * @since     1.0
155
     * @access    public
156
     * @return    string
157
     */
158
    function getName()
159
    {
160
        return $this->getAttribute('name');
161
    } //end func getName
162
 
163
    // }}}
164
    // {{{ getPrivateName()
165
 
166
    /**
167
     * Returns the element name (possibly with brackets appended)
168
     *
169
     * @since     1.0
170
     * @access    public
171
     * @return    string
172
     */
173
    function getPrivateName()
174
    {
175
        if ($this->getAttribute('multiple')) {
176
            return $this->getName() . '[]';
177
        } else {
178
            return $this->getName();
179
        }
180
    } //end func getPrivateName
181
 
182
    // }}}
183
    // {{{ setValue()
184
 
185
    /**
186
     * Sets the value of the form element
187
     *
188
     * @param     mixed    $values  Array or comma delimited string of selected values
189
     * @since     1.0
190
     * @access    public
191
     * @return    void
192
     */
193
    function setValue($value)
194
    {
195
        $this->setSelected($value);
196
    } // end func setValue
197
 
198
    // }}}
199
    // {{{ getValue()
200
 
201
    /**
202
     * Returns an array of the selected values
203
     *
204
     * @since     1.0
205
     * @access    public
206
     * @return    array of selected values
207
     */
208
    function getValue()
209
    {
210
        return $this->_values;
211
    } // end func getValue
212
 
213
    // }}}
214
    // {{{ setSize()
215
 
216
    /**
217
     * Sets the select field size, only applies to 'multiple' selects
218
     *
219
     * @param     int    $size  Size of select  field
220
     * @since     1.0
221
     * @access    public
222
     * @return    void
223
     */
224
    function setSize($size)
225
    {
226
        $this->updateAttributes(array('size' => $size));
227
    } //end func setSize
228
 
229
    // }}}
230
    // {{{ getSize()
231
 
232
    /**
233
     * Returns the select field size
234
     *
235
     * @since     1.0
236
     * @access    public
237
     * @return    int
238
     */
239
    function getSize()
240
    {
241
        return $this->getAttribute('size');
242
    } //end func getSize
243
 
244
    // }}}
245
    // {{{ setMultiple()
246
 
247
    /**
248
     * Sets the select mutiple attribute
249
     *
250
     * @param     bool    $multiple  Whether the select supports multi-selections
251
     * @since     1.2
252
     * @access    public
253
     * @return    void
254
     */
255
    function setMultiple($multiple)
256
    {
257
        if ($multiple) {
258
            $this->updateAttributes(array('multiple' => 'multiple'));
259
        } else {
260
            $this->removeAttribute('multiple');
261
        }
262
    } //end func setMultiple
263
 
264
    // }}}
265
    // {{{ getMultiple()
266
 
267
    /**
268
     * Returns the select mutiple attribute
269
     *
270
     * @since     1.2
271
     * @access    public
272
     * @return    bool    true if multiple select, false otherwise
273
     */
274
    function getMultiple()
275
    {
276
        return (bool)$this->getAttribute('multiple');
277
    } //end func getMultiple
278
 
279
    // }}}
280
    // {{{ addOption()
281
 
282
    /**
283
     * Adds a new OPTION to the SELECT
284
     *
285
     * @param     string    $text       Display text for the OPTION
286
     * @param     string    $value      Value for the OPTION
287
     * @param     mixed     $attributes Either a typical HTML attribute string
288
     *                                  or an associative array
289
     * @since     1.0
290
     * @access    public
291
     * @return    void
292
     */
293
    function addOption($text, $value, $attributes=null)
294
    {
295
        if (null === $attributes) {
296
            $attributes = array('value' => $value);
297
        } else {
298
            $attributes = $this->_parseAttributes($attributes);
299
            if (isset($attributes['selected'])) {
300
                // the 'selected' attribute will be set in toHtml()
301
                $this->_removeAttr('selected', $attributes);
302
                if (is_null($this->_values)) {
303
                    $this->_values = array($value);
304
                } elseif (!in_array($value, $this->_values)) {
305
                    $this->_values[] = $value;
306
                }
307
            }
308
            $this->_updateAttrArray($attributes, array('value' => $value));
309
        }
310
        $this->_options[] = array('text' => $text, 'attr' => $attributes);
311
    } // end func addOption
312
 
313
    // }}}
314
    // {{{ loadArray()
315
 
316
    /**
317
     * Loads the options from an associative array
318
     *
319
     * @param     array    $arr     Associative array of options
320
     * @param     mixed    $values  (optional) Array or comma delimited string of selected values
321
     * @since     1.0
322
     * @access    public
323
     * @return    PEAR_Error on error or true
324
     * @throws    PEAR_Error
325
     */
326
    function loadArray($arr, $values=null)
327
    {
328
        if (!is_array($arr)) {
329
            return PEAR::raiseError('Argument 1 of HTML_Select::loadArray is not a valid array');
330
        }
331
        if (isset($values)) {
332
            $this->setSelected($values);
333
        }
334
        foreach ($arr as $key => $val) {
335
            // Warning: new API since release 2.3
336
            $this->addOption($val, $key);
337
        }
338
        return true;
339
    } // end func loadArray
340
 
341
    // }}}
342
    // {{{ loadDbResult()
343
 
344
    /**
345
     * Loads the options from DB_result object
346
     *
347
     * If no column names are specified the first two columns of the result are
348
     * used as the text and value columns respectively
349
     * @param     object    $result     DB_result object
350
     * @param     string    $textCol    (optional) Name of column to display as the OPTION text
351
     * @param     string    $valueCol   (optional) Name of column to use as the OPTION value
352
     * @param     mixed     $values     (optional) Array or comma delimited string of selected values
353
     * @since     1.0
354
     * @access    public
355
     * @return    PEAR_Error on error or true
356
     * @throws    PEAR_Error
357
     */
358
    function loadDbResult(&$result, $textCol=null, $valueCol=null, $values=null)
359
    {
360
        if (!is_object($result) || !is_a($result, 'db_result')) {
361
            return PEAR::raiseError('Argument 1 of HTML_Select::loadDbResult is not a valid DB_result');
362
        }
363
        if (isset($values)) {
364
            $this->setValue($values);
365
        }
366
        $fetchMode = ($textCol && $valueCol) ? DB_FETCHMODE_ASSOC : DB_FETCHMODE_DEFAULT;
367
        while (is_array($row = $result->fetchRow($fetchMode)) ) {
368
            if ($fetchMode == DB_FETCHMODE_ASSOC) {
369
                $this->addOption($row[$textCol], $row[$valueCol]);
370
            } else {
371
                $this->addOption($row[0], $row[1]);
372
            }
373
        }
374
        return true;
375
    } // end func loadDbResult
376
 
377
    // }}}
378
    // {{{ loadQuery()
379
 
380
    /**
381
     * Queries a database and loads the options from the results
382
     *
383
     * @param     mixed     $conn       Either an existing DB connection or a valid dsn
384
     * @param     string    $sql        SQL query string
385
     * @param     string    $textCol    (optional) Name of column to display as the OPTION text
386
     * @param     string    $valueCol   (optional) Name of column to use as the OPTION value
387
     * @param     mixed     $values     (optional) Array or comma delimited string of selected values
388
     * @since     1.1
389
     * @access    public
390
     * @return    void
391
     * @throws    PEAR_Error
392
     */
393
    function loadQuery(&$conn, $sql, $textCol=null, $valueCol=null, $values=null)
394
    {
395
        if (is_string($conn)) {
396
            require_once('DB.php');
397
            $dbConn = &DB::connect($conn, true);
398
            if (DB::isError($dbConn)) {
399
                return $dbConn;
400
            }
401
        } elseif (is_subclass_of($conn, "db_common")) {
402
            $dbConn = &$conn;
403
        } else {
404
            return PEAR::raiseError('Argument 1 of HTML_Select::loadQuery is not a valid type');
405
        }
406
        $result = $dbConn->query($sql);
407
        if (DB::isError($result)) {
408
            return $result;
409
        }
410
        $this->loadDbResult($result, $textCol, $valueCol, $values);
411
        $result->free();
412
        if (is_string($conn)) {
413
            $dbConn->disconnect();
414
        }
415
        return true;
416
    } // end func loadQuery
417
 
418
    // }}}
419
    // {{{ load()
420
 
421
    /**
422
     * Loads options from different types of data sources
423
     *
424
     * This method is a simulated overloaded method.  The arguments, other than the
425
     * first are optional and only mean something depending on the type of the first argument.
426
     * If the first argument is an array then all arguments are passed in order to loadArray.
427
     * If the first argument is a db_result then all arguments are passed in order to loadDbResult.
428
     * If the first argument is a string or a DB connection then all arguments are
429
     * passed in order to loadQuery.
430
     * @param     mixed     $options     Options source currently supports assoc array or DB_result
431
     * @param     mixed     $param1     (optional) See function detail
432
     * @param     mixed     $param2     (optional) See function detail
433
     * @param     mixed     $param3     (optional) See function detail
434
     * @param     mixed     $param4     (optional) See function detail
435
     * @since     1.1
436
     * @access    public
437
     * @return    PEAR_Error on error or true
438
     * @throws    PEAR_Error
439
     */
440
    function load(&$options, $param1=null, $param2=null, $param3=null, $param4=null)
441
    {
442
        switch (true) {
443
            case is_array($options):
444
                return $this->loadArray($options, $param1);
445
                break;
446
            case (is_a($options, 'db_result')):
447
                return $this->loadDbResult($options, $param1, $param2, $param3);
448
                break;
443 ddelon 449
            case (is_string($options) && !empty($options) ):
320 jpm 450
                return $this->loadQuery($options, $param1, $param2, $param3, $param4);
451
                break;
452
        }
453
    } // end func load
454
 
455
    // }}}
456
    // {{{ toHtml()
457
 
458
    /**
459
     * Returns the SELECT in HTML
460
     *
461
     * @since     1.0
462
     * @access    public
463
     * @return    string
464
     */
465
    function toHtml()
466
    {
467
        if ($this->_flagFrozen) {
468
            return $this->getFrozenHtml();
469
        } else {
470
            $tabs    = $this->_getTabs();
471
            $strHtml = '';
472
 
473
            if ($this->getComment() != '') {
474
                $strHtml .= $tabs . '<!-- ' . $this->getComment() . " //-->\n";
475
            }
476
 
477
            if (!$this->getMultiple()) {
478
                $attrString = $this->_getAttrString($this->_attributes);
479
            } else {
480
                $myName = $this->getName();
481
                $this->setName($myName . '[]');
482
                $attrString = $this->_getAttrString($this->_attributes);
483
                $this->setName($myName);
484
            }
485
            $strHtml .= $tabs . '<select' . $attrString . ">\n";
486
 
487
            foreach ($this->_options as $option) {
488
                if (is_array($this->_values) && in_array((string)$option['attr']['value'], $this->_values)) {
489
                    $this->_updateAttrArray($option['attr'], array('selected' => 'selected'));
490
                }
491
                $strHtml .= $tabs . "\t<option" . $this->_getAttrString($option['attr']) . '>' .
492
                            $option['text'] . "</option>\n";
493
            }
494
 
495
            return $strHtml . $tabs . '</select>';
496
        }
497
    } //end func toHtml
498
 
499
    // }}}
500
    // {{{ getFrozenHtml()
501
 
502
    /**
503
     * Returns the value of field without HTML tags
504
     *
505
     * @since     1.0
506
     * @access    public
507
     * @return    string
508
     */
509
    function getFrozenHtml()
510
    {
511
        $value = array();
512
        if (is_array($this->_values)) {
513
            foreach ($this->_values as $key => $val) {
514
                for ($i = 0, $optCount = count($this->_options); $i < $optCount; $i++) {
443 ddelon 515
                    if ((string)$val == (string)$this->_options[$i]['attr']['value']) {
320 jpm 516
                        $value[$key] = $this->_options[$i]['text'];
517
                        break;
518
                    }
519
                }
520
            }
521
        }
522
        $html = empty($value)? '&nbsp;': join('<br />', $value);
523
        if ($this->_persistantFreeze) {
524
            $name = $this->getPrivateName();
525
            // Only use id attribute if doing single hidden input
526
            if (1 == count($value)) {
527
                $id     = $this->getAttribute('id');
443 ddelon 528
                $idAttr = isset($id)? array('id' => $id): array();
320 jpm 529
            } else {
443 ddelon 530
                $idAttr = array();
320 jpm 531
            }
532
            foreach ($value as $key => $item) {
443 ddelon 533
                $html .= '<input' . $this->_getAttrString(array(
534
                             'type'  => 'hidden',
535
                             'name'  => $name,
536
                             'value' => $this->_values[$key]
537
                         ) + $idAttr) . ' />';
320 jpm 538
            }
539
        }
540
        return $html;
541
    } //end func getFrozenHtml
542
 
543
    // }}}
544
    // {{{ exportValue()
545
 
546
   /**
547
    * We check the options and return only the values that _could_ have been
548
    * selected. We also return a scalar value if select is not "multiple"
549
    */
550
    function exportValue(&$submitValues, $assoc = false)
551
    {
552
        $value = $this->_findValue($submitValues);
553
        if (is_null($value)) {
554
            $value = $this->getValue();
555
        } elseif(!is_array($value)) {
556
            $value = array($value);
557
        }
558
        if (is_array($value) && !empty($this->_options)) {
559
            $cleanValue = null;
560
            foreach ($value as $v) {
561
                for ($i = 0, $optCount = count($this->_options); $i < $optCount; $i++) {
562
                    if ($v == $this->_options[$i]['attr']['value']) {
563
                        $cleanValue[] = $v;
564
                        break;
565
                    }
566
                }
567
            }
568
        } else {
569
            $cleanValue = $value;
570
        }
571
        if (is_array($cleanValue) && !$this->getMultiple()) {
572
            return $this->_prepareValue($cleanValue[0], $assoc);
573
        } else {
574
            return $this->_prepareValue($cleanValue, $assoc);
575
        }
576
    }
577
 
578
    // }}}
443 ddelon 579
    // {{{ onQuickFormEvent()
580
 
581
    function onQuickFormEvent($event, $arg, &$caller)
582
    {
583
        if ('updateValue' == $event) {
584
            $value = $this->_findValue($caller->_constantValues);
585
            if (null === $value) {
586
                $value = $this->_findValue($caller->_submitValues);
587
                // Fix for bug #4465
588
                // XXX: should we push this to element::onQuickFormEvent()?
589
                if (null === $value && !$caller->isSubmitted()) {
590
                    $value = $this->_findValue($caller->_defaultValues);
591
                }
592
            }
593
            if (null !== $value) {
594
                $this->setValue($value);
595
            }
596
            return true;
597
        } else {
598
            return parent::onQuickFormEvent($event, $arg, $caller);
599
        }
600
    }
601
 
602
    // }}}
320 jpm 603
} //end class HTML_QuickForm_select
604
?>