| [ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 <?php 2 3 /** 4 * Base plugin class. 5 */ 6 7 require_once 'Savant2/Plugin.php'; 8 9 10 /** 11 * 12 * Creates XHTML forms with CSS and table-based layouts. 13 * 14 * $Id: Savant2_Plugin_form.php 18360 2005-05-26 19:38:09Z mipmip $ 15 * 16 * @author Paul M. Jones <pmjones@ciaweb.net> 17 * 18 * @package Savant2 19 * 20 * @todo Add non-standard elements: date, time, hierselect, autocomplete 21 * 22 * @license http://www.gnu.org/copyleft/lesser.html LGPL 23 * 24 * This program is free software; you can redistribute it and/or modify 25 * it under the terms of the GNU Lesser General Public License as 26 * published by the Free Software Foundation; either version 2.1 of the 27 * License, or (at your option) any later version. 28 * 29 * This program is distributed in the hope that it will be useful, but 30 * WITHOUT ANY WARRANTY; without even the implied warranty of 31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 32 * Lesser General Public License for more details. 33 * 34 */ 35 36 class Savant2_Plugin_form extends Savant2_Plugin { 37 38 39 /** 40 * 41 * The CSS class to use when generating form layout. 42 * 43 * This class name will be applied to the following tags: 44 * 45 * - div 46 * - fieldset 47 * - legend 48 * - table 49 * - tr 50 * - th 51 * - td 52 * - label 53 * 54 * @access public 55 * 56 * @var array 57 * 58 */ 59 60 var $class = ''; 61 62 63 /** 64 * 65 * The default 'float' style for fieldset blocks. 66 * 67 * @access public 68 * 69 * @var string 70 * 71 */ 72 73 var $float = ''; 74 75 76 /** 77 * 78 * The default 'clear' style for fieldset blocks. 79 * 80 * @access public 81 * 82 * @var string 83 * 84 */ 85 86 var $clear = ''; 87 88 89 /** 90 * 91 * The sprintf() format for element notes in col-type blocks. 92 * 93 * @access public 94 * 95 * @var string 96 * 97 */ 98 99 var $noteCol = '<span style="font-size: 80%%; font-style: italic;">%s</span>'; 100 101 102 /** 103 * 104 * The sprintf() format for element notes in row-type blocks. 105 * 106 * @access public 107 * 108 * @var string 109 * 110 */ 111 112 var $noteRow = '<span style="font-size: 80%%; font-style: italic;">%s</span>'; 113 114 115 /** 116 * 117 * The text used to separate radio buttons in col-type blocks. 118 * 119 * @access public 120 * 121 * @var string 122 * 123 */ 124 125 var $radioCol = '<br />'; 126 127 128 /** 129 * 130 * The text used to separate radio buttons in row-type blocks. 131 * 132 * @access public 133 * 134 * @var string 135 * 136 */ 137 138 var $radioRow = ' '; 139 140 141 /** 142 * 143 * The base number of tabs to use when tidying up the generated XHTML. 144 * 145 * @access public 146 * 147 * @var int 148 * 149 */ 150 151 var $tabBase = 2; 152 153 154 /** 155 * 156 * The sprintf() format for validation messages in col-type blocks. 157 * 158 * @access public 159 * 160 * @var string 161 * 162 */ 163 164 var $validCol = '<br /><span style="color: red; font-size: 80%%;">%s</span>'; 165 166 167 /** 168 * 169 * The sprintf() format for validation messages in col-type blocks. 170 * 171 * @access public 172 * 173 * @var string 174 * 175 */ 176 177 var $validRow = '<br /><span style="color: red; font-size: 80%%;">%s</span>'; 178 179 180 /** 181 * 182 * Whether or not to automatically dispel magic quotes from values. 183 * 184 * @access public 185 * 186 * @var bool 187 * 188 */ 189 190 var $unquote = true; 191 192 193 /** 194 * 195 * Whether or not to use automatic layout. 196 * 197 * @access public 198 * 199 * @var bool 200 * 201 */ 202 203 var $layout = true; 204 205 206 /** 207 * 208 * The kind of fieldset block being generated ('col' or 'row'). 209 * 210 * @access private 211 * 212 * @var bool 213 * 214 */ 215 216 var $_blockType = null; 217 218 219 /** 220 * 221 * The legend for the fieldset block, if any. 222 * 223 * @access private 224 * 225 * @var string 226 * 227 */ 228 229 var $_blockLabel = null; 230 231 232 /** 233 * 234 * Whether or not the form is generating elements within a fieldset block. 235 * 236 * @access private 237 * 238 * @var bool 239 * 240 */ 241 242 var $_inBlock = false; 243 244 245 /** 246 * 247 * Whether or not the form is generating elements as a group. 248 * 249 * @access private 250 * 251 * @var bool 252 * 253 */ 254 255 var $_inGroup = false; 256 257 258 /** 259 * 260 * The number of tabs to use before certain tags when tidying XHTML layout. 261 * 262 * @access private 263 * 264 * @var bool 265 * 266 */ 267 268 var $_tabs = array( 269 'form' => 0, 270 '/form' => 0, 271 'div' => 1, 272 '/div' => 1, 273 'fieldset' => 1, 274 '/fieldset' => 1, 275 'legend' => 2, 276 'table' => 2, 277 '/table' => 2, 278 'tr' => 3, 279 '/tr' => 3, 280 'th' => 4, 281 '/th' => 4, 282 'td' => 4, 283 '/td' => 4, 284 'label' => 5, 285 'input type="button"' => 5, 286 'input type="checkbox"' => 5, 287 'input type="file"' => 5, 288 'input type="hidden"' => 5, 289 'input type="image"' => 5, 290 'input type="password"' => 5, 291 'input type="reset"' => 5, 292 'input type="submit"' => 5, 293 'input type="text"' => 5, 294 'textarea' => 5, 295 'select' => 5, 296 '/select' => 5, 297 'option' => 6 298 ); 299 300 301 /** 302 * 303 * Central switcher API for the the various public methods. 304 * 305 * @access public 306 * 307 * @param string $method The public method to call from this class; all 308 * additional parameters will be passed to the called method, and all 309 * returns from the mehtod will be tidied. 310 * 311 * @return string XHTML generated by the public method. 312 * 313 */ 314 315 function plugin($method) 316 { 317 // only pass calls to public methods (i.e., no leading underscore) 318 if (substr($method, 0, 1) != '_' && method_exists($this, $method)) { 319 320 // get all arguments and drop the first one (the method name) 321 $args = func_get_args(); 322 array_shift($args); 323 324 // call the method, then return the tidied-up XHTML results 325 $xhtml = call_user_func_array(array(&$this, $method), $args); 326 return $this->_tidy($xhtml); 327 } 328 } 329 330 331 /** 332 * 333 * Sets the value of a public property. 334 * 335 * @access public 336 * 337 * @param string $key The name of the property to set. 338 * 339 * @param mixed $val The new value for the property. 340 * 341 * @return void 342 * 343 */ 344 345 function set($key, $val) 346 { 347 if (substr($key, 0, 1) != '_' && isset($this->$key)) { 348 $this->$key = $val; 349 } 350 } 351 352 353 // --------------------------------------------------------------------- 354 // 355 // Form methods 356 // 357 // --------------------------------------------------------------------- 358 359 360 /** 361 * 362 * Starts the form. 363 * 364 * The form defaults to 'action="$_SERVER['REQUEST_URI']"' and 365 * 'method="post"', but you can override those, and add any other 366 * attributes you like. 367 * 368 * @access public 369 * 370 * @param array|string $attr Attributes to add to the form tag. 371 * 372 * @return A <form> tag. 373 * 374 */ 375 376 function start($attr = null) 377 { 378 // make sure there is at least an empty array of attributes 379 if (is_null($attr)) { 380 $attr = array(); 381 } 382 383 // make sure there is a default action and method from 384 // the attribute array. 385 if (is_array($attr)) { 386 387 // default action 388 if (! isset($attr['action'])) { 389 $attr['action'] = $_SERVER['REQUEST_URI']; 390 } 391 392 // default method 393 if (! isset($attr['method'])) { 394 $attr['method'] = 'post'; 395 } 396 397 // default encoding 398 if (! isset($attr['enctype'])) { 399 $attr['enctype'] = 'multipart/form-data'; 400 } 401 } 402 403 // start the form 404 $xhtml = '<form'; 405 $xhtml .= $this->_attr($attr) . ">"; 406 return $xhtml; 407 } 408 409 410 /** 411 * 412 * Ends the form and closes any existing layout. 413 * 414 * @access public 415 * 416 * @return The ending layout XHTML and a </form> tag. 417 * 418 */ 419 420 function end() 421 { 422 $xhtml = ''; 423 $xhtml .= $this->group('end'); 424 $xhtml .= $this->block('end'); 425 return $xhtml . '</form>'; 426 } 427 428 429 // --------------------------------------------------------------------- 430 // 431 // Element methods 432 // 433 // --------------------------------------------------------------------- 434 435 436 /** 437 * 438 * Generates a 'button' element. 439 * 440 * @access public 441 * 442 * @param string $name The element name. 443 * 444 * @param mixed $value The element value. 445 * 446 * @param string $label The element label. 447 * 448 * @param array|string $attr Attributes for the element tag. 449 * 450 * @param mixed $validCode A validation code. If exactly boolean 451 * true, or exactly null, no validation message will be displayed. 452 * If any other integer, string, or array value, the element is 453 * treated as not-valid and will display the corresponding message. 454 * 455 * @param mixed array|string $validMsg A validation message. If an 456 * array, the $validCode value is used as a key for this array to 457 * determine which message(s) should be displayed. 458 * 459 * @return string The element XHTML. 460 * 461 */ 462 463 function button($name, $value = null, $label = null, $attr = null, 464 $validCode = null, $validMsg = null) 465 { 466 $xhtml = $this->_input('button', $name, $value, $attr); 467 return $this->_element($label, $xhtml, $validCode, $validMsg); 468 } 469 470 471 /** 472 * 473 * Generates a 'checkbox' element. 474 * 475 * @access public 476 * 477 * @param string $name The element name. 478 * 479 * @param mixed $value The element value. 480 * 481 * @param string $label The element label. 482 * 483 * @param mixed $options If a scalar (single value), then value of the 484 * checkbox when checked; if an array, element 0 is the value when 485 * checked, and element 1 is the value when not-checked. 486 * 487 * @param array|string $attr Attributes for the element tag. 488 * 489 * @param mixed $validCode A validation code. If exactly boolean 490 * true, or exactly null, no validation message will be displayed. 491 * If any other integer, string, or array value, the element is 492 * treated as not-valid and will display the corresponding message. 493 * 494 * @param mixed array|string $validMsg A validation message. If an 495 * array, the $validCode value is used as a key for this array to 496 * determine which message(s) should be displayed. 497 * 498 * @return string The element XHTML. 499 * 500 */ 501 502 function checkbox($name, $value = null, $label = null, $options = null, 503 $attr = null, $validCode = null, $validMsg = null) 504 { 505 if (is_null($options)) { 506 $options = array(1, 0); 507 } else { 508 settype($options, 'array'); 509 } 510 511 $options = $this->_unquote($options); 512 513 if (isset($options[1])) { 514 $xhtml = $this->_input('hidden', $name, $options[1]); 515 } else { 516 $xhtml = ''; 517 } 518 519 $xhtml .= '<input type="checkbox"'; 520 $xhtml .= ' name="' . htmlspecialchars($name) . '"'; 521 $xhtml .= ' value="' . htmlspecialchars($options[0]) . '"'; 522 523 if ($value == $options[0]) { 524 $xhtml .= ' checked="checked"'; 525 } 526 527 $xhtml .= $this->_attr($attr); 528 $xhtml .= ' />'; 529 return $this->_element($label, $xhtml, $validCode, $validMsg); 530 } 531 532 533 /** 534 * 535 * Generates a 'file' element. 536 * 537 * @access public 538 * 539 * @param string $name The element name. 540 * 541 * @param mixed $value The element value. 542 * 543 * @param string $label The element label. 544 * 545 * @param array|string $attr Attributes for the element tag. 546 * 547 * @param mixed $validCode A validation code. If exactly boolean 548 * true, or exactly null, no validation message will be displayed. 549 * If any other integer, string, or array value, the element is 550 * treated as not-valid and will display the corresponding message. 551 * 552 * @param mixed array|string $validMsg A validation message. If an 553 * array, the $validCode value is used as a key for this array to 554 * determine which message(s) should be displayed. 555 * 556 * @return string The element XHTML. 557 * 558 */ 559 560 function file($name, $value = null, $label = null, $attr = null, 561 $validCode = null, $validMsg = null) 562 { 563 $xhtml = $this->_input('file', $name, $value, $attr); 564 return $this->_element($label, $xhtml, $validCode, $validMsg); 565 } 566 567 568 /** 569 * 570 * Generates a 'hidden' element (no layout is generated). 571 * 572 * @access public 573 * 574 * @param string $name The element name. 575 * 576 * @param mixed $value The element value. 577 * 578 * @param array|string $attr Attributes for the element tag. 579 * 580 * @return string The element XHTML. 581 * 582 */ 583 584 function hidden($name, $value = null, $attr = null) 585 { 586 return $this->_input('hidden', $name, $value, $attr); 587 } 588 589 590 /** 591 * 592 * Generates an 'image' element. 593 * 594 * @access public 595 * 596 * @param string $name The element name. 597 * 598 * @param mixed $src The image HREF source. 599 * 600 * @param string $label The element label. 601 * 602 * @param array|string $attr Attributes for the element tag. 603 * 604 * @param mixed $validCode A validation code. If exactly boolean 605 * true, or exactly null, no validation message will be displayed. 606 * If any other integer, string, or array value, the element is 607 * treated as not-valid and will display the corresponding message. 608 * 609 * @param mixed array|string $validMsg A validation message. If an 610 * array, the $validCode value is used as a key for this array to 611 * determine which message(s) should be displayed. 612 * 613 * @return string The element XHTML. 614 * 615 */ 616 617 function image($name, $src, $label = null, $attr = null, $validCode = null, 618 $validMsg = null) 619 { 620 $xhtml = '<input type="image"'; 621 $xhtml .= ' name="' . htmlspecialchars($name) . '"'; 622 $xhtml .= ' src="' . htmlspecialchars($src) . '"'; 623 $xhtml .= $this->_attr($attr); 624 $xhtml .= ' />'; 625 return $this->_element($label, $xhtml, $validCode, $validMsg); 626 } 627 628 629 /** 630 * 631 * Generates a 'password' element. 632 * 633 * @access public 634 * 635 * @param string $name The element name. 636 * 637 * @param mixed $value The element value. 638 * 639 * @param string $label The element label. 640 * 641 * @param array|string $attr Attributes for the element tag. 642 * 643 * @param mixed $validCode A validation code. If exactly boolean 644 * true, or exactly null, no validation message will be displayed. 645 * If any other integer, string, or array value, the element is 646 * treated as not-valid and will display the corresponding message. 647 * 648 * @param mixed array|string $validMsg A validation message. If an 649 * array, the $validCode value is used as a key for this array to 650 * determine which message(s) should be displayed. 651 * 652 * @return string The element XHTML. 653 * 654 */ 655 656 function password($name, $value = null, $label = null, $attr = null, 657 $validCode = null, $validMsg = null) 658 { 659 $xhtml = $this->_input('password', $name, $value, $attr); 660 return $this->_element($label, $xhtml, $validCode, $validMsg); 661 } 662 663 664 /** 665 * 666 * Generates a set of radio button elements. 667 * 668 * @access public 669 * 670 * @param string $name The element name. 671 * 672 * @param mixed $value The radio value to mark as 'checked'. 673 * 674 * @param string $label The element label. 675 * 676 * @param array $options An array of key-value pairs where the array 677 * key is the radio value, and the array value is the radio text. 678 * 679 * @param array|string $attr Attributes added to each radio. 680 * 681 * @param mixed $validCode A validation code. If exactly boolean 682 * true, or exactly null, no validation message will be displayed. 683 * If any other integer, string, or array value, the element is 684 * treated as not-valid and will display the corresponding message. 685 * 686 * @param mixed array|string $validMsg A validation message. If an 687 * array, the $validCode value is used as a key for this array to 688 * determine which message(s) should be displayed. 689 * 690 * @return string The radio buttons XHTML. 691 * 692 */ 693 694 function radio($name, $value = null, $label = null, $options = null, 695 $attr = null, $validCode = null, $validMsg = null) 696 { 697 settype($options, 'array'); 698 $value = $this->_unquote($value); 699 700 $list = array(); 701 foreach ($options as $optval => $optlabel) { 702 $radio = '<label style="white-space: nowrap;"><input type="radio"'; 703 $radio .= ' name="' . htmlspecialchars($name) . '"'; 704 $radio .= ' value="' . htmlspecialchars($optval) . '"'; 705 706 if ($optval == $value) { 707 $radio .= ' checked="checked"'; 708 } 709 710 $radio .= ' />' . htmlspecialchars($optlabel) . '</label>'; 711 $list[] = $radio; 712 713 } 714 715 // pick the separator string 716 if ($this->_inBlock && $this->_blockType == 'row') { 717 $sep = $this->radioRow; 718 } else { 719 $sep = $this->radioCol; 720 } 721 722 // done! 723 $xhtml = implode($sep, $list); 724 return $this->_element($label, $xhtml, $validCode, $validMsg); 725 } 726 727 728 /** 729 * 730 * Generates a 'reset' button. 731 * 732 * @access public 733 * 734 * @param string $name The element name. 735 * 736 * @param mixed $value The element value. 737 * 738 * @param string $label The element label. 739 * 740 * @param array|string $attr Attributes for the element tag. 741 * 742 * @param mixed $validCode A validation code. If exactly boolean 743 * true, or exactly null, no validation message will be displayed. 744 * If any other integer, string, or array value, the element is 745 * treated as not-valid and will display the corresponding message. 746 * 747 * @param mixed array|string $validMsg A validation message. If an 748 * array, the $validCode value is used as a key for this array to 749 * determine which message(s) should be displayed. 750 * 751 * @return string The element XHTML. 752 * 753 */ 754 755 function reset($name, $value = null, $label = null, $attr = null, 756 $validCode = null, $validMsg = null) 757 { 758 $xhtml = $this->_input('reset', $name, $value, $attr); 759 return $this->_element($label, $xhtml, $validCode, $validMsg); 760 } 761 762 763 /** 764 * 765 * Generates 'select' list of options. 766 * 767 * @access public 768 * 769 * @param string $name The element name. 770 * 771 * @param mixed $value The option value to mark as 'selected'; if an 772 * array, will mark all values in the array as 'selected' (used for 773 * multiple-select elements). 774 * 775 * @param string $label The element label. 776 * 777 * @param array $options An array of key-value pairs where the array 778 * key is the radio value, and the array value is the radio text. 779 * 780 * @param array|string $attr Attributes added to the 'select' tag. 781 * 782 * @param mixed $validCode A validation code. If exactly boolean 783 * true, or exactly null, no validation message will be displayed. 784 * If any other integer, string, or array value, the element is 785 * treated as not-valid and will display the corresponding message. 786 * 787 * @param mixed array|string $validMsg A validation message. If an 788 * array, the $validCode value is used as a key for this array to 789 * determine which message(s) should be displayed. 790 * 791 * @return string The select tag and options XHTML. 792 * 793 */ 794 795 function select($name, $value = null, $label = null, $options = null, 796 $attr = null, $validCode = null, $validMsg = null) 797 { 798 settype($value, 'array'); 799 settype($options, 'array'); 800 801 $value = $this->_unquote($value); 802 803 $xhtml = ''; 804 $xhtml .= '<select name="' . htmlspecialchars($name) . '"'; 805 $xhtml .= $this->_attr($attr); 806 $xhtml .= '>'; 807 808 $list = array(); 809 foreach ($options as $optval => $optlabel) { 810 $opt = '<option value="' . htmlspecialchars($optval) . '"'; 811 $opt .= ' label="' . htmlspecialchars($optlabel) . '"'; 812 if (in_array($optval, $value)) { 813 $opt .= ' selected="selected"'; 814 } 815 $opt .= '>' . htmlspecialchars($optlabel) . "</option>"; 816 $list[] = $opt; 817 } 818 819 $xhtml .= implode('', $list); 820 $xhtml .= '</select>'; 821 return $this->_element($label, $xhtml, $validCode, $validMsg); 822 } 823 824 825 /** 826 * 827 * Generates a 'submit' button. 828 * 829 * @access public 830 * 831 * @param string $name The element name. 832 * 833 * @param mixed $value The element value. 834 * 835 * @param string $label The element label. 836 * 837 * @param array|string $attr Attributes for the element tag. 838 * 839 * @param mixed $validCode A validation code. If exactly boolean 840 * true, or exactly null, no validation message will be displayed. 841 * If any other integer, string, or array value, the element is 842 * treated as not-valid and will display the corresponding message. 843 * 844 * @param mixed array|string $validMsg A validation message. If an 845 * array, the $validCode value is used as a key for this array to 846 * determine which message(s) should be displayed. 847 * 848 * @return string The element XHTML. 849 * 850 */ 851 852 function submit($name, $value = null, $label = null, $attr = null, 853 $validCode = null, $validMsg = null) 854 { 855 $xhtml = $this->_input('submit', $name, $value, $attr); 856 return $this->_element($label, $xhtml, $validCode, $validMsg); 857 } 858 859 860 /** 861 * 862 * Adds a note to the form. 863 * 864 * @access public 865 * 866 * @param string $text The note text. 867 * 868 * @param string $label The label, if any, for the note. 869 * 870 * @param mixed $validCode A validation code. If exactly boolean 871 * true, or exactly null, no validation message will be displayed. 872 * If any other integer, string, or array value, the element is 873 * treated as not-valid and will display the corresponding message. 874 * 875 * @param mixed array|string $validMsg A validation message. If an 876 * array, the $validCode value is used as a key for this array to 877 * determine which message(s) should be displayed. 878 * 879 * @return string The element XHTML. 880 * 881 */ 882 883 function note($text, $label = null, $validCode = null, $validMsg = null) 884 { 885 // pick the format 886 if ($this->_inBlock && $this->_blockType == 'row') { 887 $format = $this->noteRow; 888 } else { 889 $format = $this->noteCol; 890 } 891 892 // don't show the format when there's no note 893 if (trim($text) == '') { 894 $xhtml = ''; 895 } else { 896 $xhtml = sprintf($format, $text); 897 } 898 899 // format and return 900 return $this->_element($label, $xhtml, $validCode, $validMsg); 901 } 902 903 904 /** 905 * 906 * Generates a 'text' element. 907 * 908 * @access public 909 * 910 * @param string $name The element name. 911 * 912 * @param mixed $value The element value. 913 * 914 * @param string $label The element label. 915 * 916 * @param array|string $attr Attributes for the element tag. 917 * 918 * @param mixed $validCode A validation code. If exactly boolean 919 * true, or exactly null, no validation message will be displayed. 920 * If any other integer, string, or array value, the element is 921 * treated as not-valid and will display the corresponding message. 922 * 923 * @param mixed array|string $validMsg A validation message. If an 924 * array, the $validCode value is used as a key for this array to 925 * determine which message(s) should be displayed. 926 * 927 * @return string The element XHTML. 928 * 929 */ 930 931 function text($name, $value = null, $label = null, $attr = null, 932 $validCode = null, $validMsg = null) 933 { 934 $xhtml = $this->_input('text', $name, $value, $attr); 935 return $this->_element($label, $xhtml, $validCode, $validMsg); 936 } 937 938 939 /** 940 * 941 * Generates a 'textarea' element. 942 * 943 * @access public 944 * 945 * @param string $name The element name. 946 * 947 * @param mixed $value The element value. 948 * 949 * @param string $label The element label. 950 * 951 * @param array|string $attr Attributes for the element tag. 952 * 953 * @param mixed $validCode A validation code. If exactly boolean 954 * true, or exactly null, no validation message will be displayed. 955 * If any other integer, string, or array value, the element is 956 * treated as not-valid and will display the corresponding message. 957 * 958 * @param mixed array|string $validMsg A validation message. If an 959 * array, the $validCode value is used as a key for this array to 960 * determine which message(s) should be displayed. 961 * 962 * @return string The element XHTML. 963 * 964 */ 965 966 function textarea($name, $value = null, $label = null, $attr = null, 967 $validCode = null, $validMsg = null) 968 { 969 $value = $this->_unquote($value); 970 $xhtml = ''; 971 $xhtml .= '<textarea name="' . htmlspecialchars($name) . '"'; 972 $xhtml .= $this->_attr($attr); 973 $xhtml .= '>' . htmlspecialchars($value) . '</textarea>'; 974 return $this->_element($label, $xhtml, $validCode, $validMsg); 975 } 976 977 978 // --------------------------------------------------------------------- 979 // 980 // Layout methods 981 // 982 // --------------------------------------------------------------------- 983 984 985 /** 986 * 987 * Builds XHTML to start, end, or split layout blocks. 988 * 989 * @param string $action Whether to 'start', 'split', or 'end' a block. 990 * 991 * @param string $label The fieldset legend. If an empty string, 992 * builds a fieldset with no legend; if null, builds a div (not a 993 * fieldset). 994 * 995 * @param string $type The layout type to use, 'col' or 'row'. The 996 * 'col' layout uses a left-column for element labels and a 997 * right-column for the elements; the 'row' layout shows the elements 998 * left-to-right, with the element label over the element, all in a 999 * single row. 1000 * 1001 * @param string $float Whether the block should float 'left' or 1002 * 'right' (set to an empty string if you don't want floating). 1003 * Defaults to the value of $this->float. 1004 * 1005 * @param string $float Whether the block should be cleared of 'left' 1006 * or 'right' floating blocks (set to an empty string if you don't 1007 * want to clear). Defaults to the value of $this->clear. 1008 * 1009 * @return string The appropriate XHTML for the block action. 1010 * 1011 */ 1012 1013 function block($action = 'start', $label = null, $type = 'col', 1014 $float = null, $clear = null) 1015 { 1016 if (is_null($float)) { 1017 $float = $this->float; 1018 } 1019 1020 if (is_null($clear)) { 1021 $clear = $this->clear; 1022 } 1023 1024 switch (strtolower($action)) { 1025 1026 case 'start': 1027 return $this->_blockStart($label, $type, $float, $clear); 1028 break; 1029 1030 case 'split': 1031 return $this->_blockSplit(); 1032 break; 1033 1034 case 'end': 1035 return $this->_blockEnd(); 1036 break; 1037 1038 } 1039 1040 return; 1041 } 1042 1043 /** 1044 * 1045 * Builds the layout for a group of elements; auto-starts a block if needed. 1046 * 1047 * @access public 1048 * 1049 * @param string $type Whether to 'start' or 'end' the group. 1050 * 1051 * @param string $label The label for the group. 1052 * 1053 * @return string The element-group layout XHTML. 1054 * 1055 */ 1056 1057 function group($type, $label = null) 1058 { 1059 // the XHTML to return 1060 $xhtml = ''; 1061 1062 // if not using automated layout, stop now. 1063 if (! $this->layout) { 1064 return $xhtml; 1065 } 1066 1067 // if not in a block, start one 1068 if (! $this->_inBlock) { 1069 $xhtml .= $this->block(); 1070 } 1071 1072 // are we starting a new group? 1073 if ($type == 'start' && ! $this->_inGroup) { 1074 1075 // build a 'col' group? 1076 if ($this->_blockType == 'col') { 1077 $xhtml .= $this->_tag('tr'); 1078 $xhtml .= $this->_tag('th'); 1079 1080 // add a label if specified 1081 if (! is_null($label)) { 1082 $xhtml .= $this->_tag('label'); 1083 $xhtml .= htmlspecialchars($label); 1084 $xhtml .= '</label>'; 1085 } 1086 $xhtml .= '</th>'; 1087 $xhtml .= $this->_tag('td'); 1088 } 1089 1090 // build a 'row' group? 1091 if ($this->_blockType == 'row') { 1092 $xhtml .= $this->_tag('td'); 1093 if (! is_null($label)) { 1094 $xhtml .= $this->_tag('label'); 1095 $xhtml .= htmlspecialchars($label); 1096 $xhtml .= '</label><br />'; 1097 } 1098 } 1099 1100 // we're in a group now 1101 $this->_inGroup = true; 1102 1103 } 1104 1105 // are we ending a current group? 1106 if ($type == 'end' && $this->_inGroup) { 1107 1108 // we're out of the group now 1109 $this->_inGroup = false; 1110 1111 if ($this->_blockType == 'col') { 1112 $xhtml .= '</td></tr>'; 1113 } 1114 1115 if ($this->_blockType == 'row') { 1116 $xhtml .= '</td>'; 1117 } 1118 } 1119 1120 // done! 1121 return $xhtml; 1122 } 1123 1124 1125 // --------------------------------------------------------------------- 1126 // 1127 // Private support methods 1128 // 1129 // --------------------------------------------------------------------- 1130 1131 1132 /** 1133 * 1134 * Builds an attribute string for a tag. 1135 * 1136 * @access private 1137 * 1138 * @param array|string $attr The attributes to add to a tag; if an array, 1139 * the key is the attribute name and the value is the attribute value; if a 1140 * string, adds the literal string to the tag. 1141 * 1142 * @return string A string of tag attributes. 1143 * 1144 */ 1145 1146 function _attr($attr = null) 1147 { 1148 if (is_array($attr)) { 1149 // add from array 1150 $xhtml = ''; 1151 foreach ($attr as $key => $val) { 1152 $key = htmlspecialchars($key); 1153 $val = htmlspecialchars($val); 1154 $xhtml .= " $key=\"$val\""; 1155 } 1156 } elseif (! is_null($attr)) { 1157 // add from scalar 1158 $xhtml = " $attr"; 1159 } else { 1160 $xhtml = null; 1161 } 1162 1163 return $xhtml; 1164 } 1165 1166 1167 /** 1168 * 1169 * Builds an XHTML opening tag with class and attributes. 1170 * 1171 * @access private 1172 * 1173 * @param string $type The tag type ('td', 'th', 'div', etc). 1174 * 1175 * @param array|string $attr Additional attributes for the tag. 1176 * 1177 * @return string The opening tag XHTML. 1178 * 1179 */ 1180 1181 function _tag($type, $attr = null) 1182 { 1183 // open the tag 1184 $xhtml = '<' . $type; 1185 1186 // add a CSS class attribute 1187 if ($this->class) { 1188 $xhtml .= ' class="' . $this->class . '"'; 1189 } 1190 1191 // add other attributes 1192 $xhtml .= $this->_attr($attr); 1193 1194 // done! 1195 return $xhtml . ">"; 1196 } 1197 1198 1199 /** 1200 * 1201 * Adds an element to the table layout; auto-starts a block as needed. 1202 * 1203 * @access private 1204 * 1205 * @param string $label The label for the element. 1206 * 1207 * @param string $fieldXhtml The XHTML for the element field. 1208 * 1209 * @param mixed $validCode A validation code. If exactly boolean 1210 * true, or exactly null, no validation message will be displayed. 1211 * If any other integer, string, or array value, the element is 1212 * treated as not-valid and will display the corresponding message. 1213 * 1214 * @param mixed array|string $validMsg A validation message. If an 1215 * array, the $validCode value is used as a key for this array to 1216 * determine which message(s) should be displayed. 1217 * 1218 * @return string The element layout XHTML. 1219 * 1220 */ 1221 1222 function _element($label, $fieldXhtml, $validCode = null, $validMsg = null) 1223 { 1224 // the XHTML to return 1225 $xhtml = ''; 1226 1227 // if we're starting an element without having started 1228 // a block first, forcibly start a default block 1229 if (! $this->_inBlock) { 1230 1231 // is there a label for the element? 1232 if (is_null($label)) { 1233 // not in a block, and no label specified. this is most 1234 // likely a hidden element above the form itself. just 1235 // return the XHTML as it is, no layout at all. 1236 return $fieldXhtml; 1237 } else { 1238 // start a block and continue 1239 $xhtml .= $this->block(); 1240 } 1241 } 1242 1243 // are we checking validation and adding validation messages? 1244 if ($validCode === null || $validCode === true) { 1245 1246 // do nothing 1247 1248 } else { 1249 1250 // force to arrays so we can have multiple messages. 1251 settype($validCode, 'array'); 1252 settype($validMsg, 'array'); 1253 1254 // pick the format 1255 if ($this->_inBlock && $this->_blockType == 'row') { 1256 $format = $this->validRow; 1257 } else { 1258 $format = $this->validCol; 1259 } 1260 1261 // add the validation messages 1262 foreach ($validCode as $code) { 1263 if (isset($validMsg[$code])) { 1264 // print the message 1265 $fieldXhtml .= sprintf( 1266 $format, 1267 $validMsg[$code] 1268 ); 1269 } else { 1270 // print the code 1271 $fieldXhtml .= sprintf( 1272 $format, 1273 $code 1274 ); 1275 } 1276 } 1277 } 1278 1279 // are we in a group? 1280 if (! $this->_inGroup) { 1281 // no, put the element in a group by itself 1282 $xhtml .= $this->group('start', $label); 1283 $xhtml .= $fieldXhtml; 1284 $xhtml .= $this->group('end'); 1285 } else { 1286 // yes, just add the element to the current group. 1287 // elements in groups do not get their own labels, 1288 // the group has already set the label. 1289 $xhtml .= $fieldXhtml; 1290 } 1291 1292 // done! 1293 return $xhtml; 1294 } 1295 1296 1297 /** 1298 * 1299 * Recursively removes magic quotes from values and arrays. 1300 * 1301 * @access private 1302 * 1303 * @param mixed $value The value from which to remove magic quotes. 1304 * 1305 * @return mixed The un-quoted value. 1306 * 1307 */ 1308 1309 function _unquote($value) 1310 { 1311 if (! $this->unquote) { 1312 return $value; 1313 } 1314 1315 static $mq; 1316 if (! isset($mq)) { 1317 $mq = get_magic_quotes_gpc() || get_magic_quotes_runtime(); 1318 } 1319 1320 if ($mq) { 1321 if (is_array($value)) { 1322 foreach ($value as $k => $v) { 1323 $value[$k] = $this->_unquote($v); 1324 } 1325 } else { 1326 $value = stripslashes($value); 1327 } 1328 } 1329 1330 return $value; 1331 } 1332 1333 1334 /** 1335 * 1336 * Builds an 'input' element. 1337 * 1338 * @access private 1339 * 1340 * @param string $type The input type ('text', 'hidden', etc). 1341 * 1342 * @param string $name The element name. 1343 * 1344 * @param mixed $value The element value. 1345 * 1346 * @param array|string $attr Attributes for the element tag. 1347 * 1348 * @return The 'input' tag XHTML. 1349 * 1350 */ 1351 1352 function _input($type, $name, $value = null, $attr = null) 1353 { 1354 $value = $this->_unquote($value); 1355 $xhtml = '<input type="' . $type . '"'; 1356 $xhtml .= ' name="' . htmlspecialchars($name) . '"'; 1357 $xhtml .= ' value="' . htmlspecialchars($value) . '"'; 1358 $xhtml .= $this->_attr($attr); 1359 $xhtml .= ' />'; 1360 return $xhtml; 1361 } 1362 1363 1364 /** 1365 * 1366 * Puts in newlines and tabs to make the source code readable. 1367 * 1368 * @access private 1369 * 1370 * @param string $xhtml The XHTML to tidy up. 1371 * 1372 * @return string The tidied XHTML. 1373 * 1374 */ 1375 1376 function _tidy($xhtml) 1377 { 1378 // only tidy up if layout is turned on 1379 if ($this->layout) { 1380 foreach ($this->_tabs as $key => $val) { 1381 $key = '<' . $key; 1382 $pad = str_pad('', $val + $this->tabBase, "\t"); 1383 $xhtml = str_replace($key, "\n$pad$key", $xhtml); 1384 } 1385 } 1386 return $xhtml; 1387 } 1388 1389 1390 /** 1391 * 1392 * Generates XHTML to start a fieldset block. 1393 * 1394 * @access private 1395 * 1396 * @param string $label The fieldset legend. If an empty string, 1397 * builds a fieldset with no legend; if null, builds a div (not a 1398 * fieldset). 1399 * 1400 * @param string $type The layout type to use, 'col' or 'row'. The 1401 * 'col' layout uses a left-column for element labels and a 1402 * right-column for the elements; the 'row' layout shows the elements 1403 * left-to-right, with the element label over the element, all in a 1404 * single row. 1405 * 1406 * @param string $float Whether the block should float 'left' or 1407 * 'right' (set to an empty string if you don't want floating). 1408 * Defaults to the value of $this->float. 1409 * 1410 * @param string $float Whether the block should be cleared of 'left' 1411 * or 'right' floating blocks (set to an empty string if you don't 1412 * want to clear). Defaults to the value of $this->clear. 1413 * 1414 * @return string The XHTML to start a block. 1415 * 1416 */ 1417 1418 function _blockStart($label = null, $type = 'col', $float = null, 1419 $clear = null) 1420 { 1421 // the XHTML text to return. 1422 $xhtml = ''; 1423 1424 // if not using automated layout, stop now. 1425 if (! $this->layout) { 1426 return $xhtml; 1427 } 1428 1429 // are we already in a block? if so, end the current one 1430 // so we can start a new one. 1431 if ($this->_inBlock) { 1432 $xhtml .= $this->block('end'); 1433 } 1434 1435 // set the new block type and label 1436 $this->_inBlock = true; 1437 $this->_blockType = $type; 1438 $this->_blockLabel = $label; 1439 1440 // build up the "style" attribute for the new block 1441 $style = ''; 1442 1443 if ($float) { 1444 $style .= " float: $float;"; 1445 } 1446 1447 if ($clear) { 1448 $style .= " clear: $clear;"; 1449 } 1450 1451 if (! empty($style)) { 1452 $attr = 'style="' . trim($style) . '"'; 1453 } else { 1454 $attr = null; 1455 } 1456 1457 // build the block opening XHTML itself; use a fieldset when a label 1458 // is specifed, or a div when the label is not specified 1459 if (is_string($this->_blockLabel)) { 1460 1461 // has a label, use a fieldset with e style attribute 1462 $xhtml .= $this->_tag('fieldset', $attr); 1463 1464 // add the label as a legend, if it exists 1465 if (! empty($this->_blockLabel)) { 1466 $xhtml .= $this->_tag('legend'); 1467 $xhtml .= htmlspecialchars($this->_blockLabel); 1468 $xhtml .= '</legend>'; 1469 } 1470 1471 } else { 1472 // no label, use a div with the style attribute 1473 $xhtml .= $this->_tag('div', $attr); 1474 } 1475 1476 // start a table for the block elements 1477 $xhtml .= $this->_tag('table'); 1478 1479 // if the block is row-based, start a row 1480 if ($this->_blockType == 'row') { 1481 $xhtml .= $this->_tag('tr'); 1482 } 1483 1484 // done! 1485 return $xhtml; 1486 } 1487 1488 1489 /** 1490 * 1491 * Generates the XHTML to end a block. 1492 * 1493 * @access public 1494 * 1495 * @return string The XHTML to end a block. 1496 * 1497 */ 1498 1499 function _blockEnd() 1500 { 1501 // the XHTML to return 1502 $xhtml = ''; 1503 1504 // if not using automated layout, stop now. 1505 if (! $this->layout) { 1506 return $xhtml; 1507 } 1508 1509 // if not in a block, return right away 1510 if (! $this->_inBlock) { 1511 return; 1512 } 1513 1514 // are we in a group? if so, end it. 1515 if ($this->_inGroup) { 1516 $xhtml .= $this->group('end'); 1517 } 1518 1519 // end the block layout proper 1520 if ($this->_blockType == 'row') { 1521 // previous block was type 'row' 1522 $xhtml .= '</tr></table>'; 1523 } else { 1524 // previous block was type 'col' 1525 $xhtml .= '</table>'; 1526 } 1527 1528 // end the fieldset or div tag for the block 1529 if (is_string($this->_blockLabel)) { 1530 // there was a label, so the block used fieldset 1531 $xhtml .= '</fieldset>'; 1532 } else { 1533 // there was no label, so the block used div 1534 $xhtml .= '</div>'; 1535 } 1536 1537 // reset tracking properties 1538 $this->_inBlock = false; 1539 $this->_blockType = null; 1540 $this->_blockLabel = null; 1541 1542 // done! 1543 return $xhtml; 1544 } 1545 1546 1547 /** 1548 * 1549 * Generates the layout to split the layout within a block. 1550 * 1551 * @access public 1552 * 1553 * @return string The XHTML to split the layout with in a block. 1554 * 1555 */ 1556 1557 function _blockSplit() 1558 { 1559 // the XHTML to return 1560 $xhtml = ''; 1561 1562 // if not using automated layout, stop now. 1563 if (! $this->layout) { 1564 return $xhtml; 1565 } 1566 1567 // not already in a block, so don't bother. 1568 if (! $this->_inBlock) { 1569 return; 1570 } 1571 1572 // end any group we might already be in 1573 if ($this->_inGroup) { 1574 $xhtml .= $this->group('end'); 1575 } 1576 1577 // end the current block and start a new one 1578 switch ($this->_blockType) { 1579 1580 case 'row': 1581 $xhtml .= '</tr>'; 1582 $xhtml .= $this->_tag('tr'); 1583 break; 1584 1585 case 'col': 1586 $xhtml .= '</table>'; 1587 $xhtml .= $this->_tag('table'); 1588 break; 1589 } 1590 1591 // done! 1592 return $xhtml; 1593 } 1594 } 1595 1596 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |