[ Index ] |
|
Code source de Symfony 1.0.0 |
1 <?php 2 3 /** 4 * sfChoiceFormat class file. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the BSD License. 8 * 9 * Copyright(c) 2004 by Qiang Xue. All rights reserved. 10 * 11 * To contact the author write to {@link mailto:qiang.xue@gmail.com Qiang Xue} 12 * The latest version of PRADO can be obtained from: 13 * {@link http://prado.sourceforge.net/} 14 * 15 * @author Wei Zhuo <weizhuo[at]gmail[dot]com> 16 * @version $Id: sfChoiceFormat.class.php 3148 2007-01-04 19:34:28Z fabien $ 17 * @package symfony 18 * @subpackage i18n 19 */ 20 21 22 /** 23 * sfChoiceFormat class. 24 * 25 * sfChoiceFormat converts between ranges of numeric values and string 26 * names for those ranges. 27 * 28 * A sfChoiceFormat splits the real number line -Inf to +Inf into two or 29 * more contiguous ranges. Each range is mapped to a string. 30 * sfChoiceFormat is generally used in a MessageFormat for displaying 31 * grammatically correct plurals such as "There are 2 files." 32 * 33 * <code> 34 * $string = '[0] are no files |[1] is one file |(1,Inf] are {number} files'; 35 * 36 * $formatter = new sfMessageFormat(...); //init for a source 37 * $translated = $formatter->format($string); 38 * 39 * $choice = new sfChoiceFormat(); 40 * echo $choice->format($translated, 0); //shows "are no files" 41 * </code> 42 * 43 * The message/string choices are separated by the pipe "|" followed 44 * by a set notation of the form 45 * # <t>[1,2]</t> -- accepts values between 1 and 2, inclusive. 46 * # <t>(1,2)</t> -- accepts values between 1 and 2, excluding 1 and 2. 47 * # <t>{1,2,3,4}</t> -- only values defined in the set are accepted. 48 * # <t>[-Inf,0)</t> -- accepts value greater or equal to negative infinity 49 * and strictly less than 0 50 * Any non-empty combinations of the delimiters of square and round brackets 51 * are acceptable. 52 * 53 * @author Xiang Wei Zhuo <weizhuo[at]gmail[dot]com> 54 * @version v1.0, last update on Fri Dec 24 20:46:16 EST 2004 55 * @package System.I18N.core 56 */ 57 class sfChoiceFormat 58 { 59 /** 60 * The pattern to validate a set notation 61 * 62 * @var string 63 */ 64 protected $validate = '/[\(\[\{]|[-Inf\d]+|,|[\+Inf\d]+|[\)\]\}]/ms'; 65 66 /** 67 * The pattern to parse the formatting string. 68 * 69 * @var string 70 */ 71 protected $parse = '/\s?\|?([\(\[\{]([-Inf\d]+,?[\+Inf\d]*)+[\)\]\}])\s?/'; 72 73 /** 74 * The value for positive infinity. 75 * 76 * @var float 77 */ 78 protected $inf; 79 80 /** 81 * Constructor. 82 */ 83 public function __construct() 84 { 85 $this->inf = -log(0); 86 } 87 88 /** 89 * Determine if the given number belongs to a given set 90 * 91 * @param float the number to test. 92 * @param string the set, in set notation. 93 * @return boolean true if number is in the set, false otherwise. 94 */ 95 public function isValid($number, $set) 96 { 97 $n = preg_match_all($this->validate, $set, $matches, PREG_SET_ORDER); 98 99 if ($n < 3) 100 { 101 $error = 'Invalid set "%s"'; 102 $error = sprintf($error, $set); 103 throw new sfException($error); 104 } 105 106 $leftBracket = $matches[0][0]; 107 $rightBracket = $matches[$n - 1][0]; 108 109 $i = 0; 110 $elements = array(); 111 112 foreach ($matches as $match) 113 { 114 $string = $match[0]; 115 if ($i != 0 && $i != $n - 1 && $string !== ',') 116 { 117 if ($string == '-Inf') 118 { 119 $elements[] = -1 * $this->inf; 120 } 121 else if ($string == '+Inf' || $string == 'Inf') 122 { 123 $elements[] = $this->inf; 124 } 125 else 126 { 127 $elements[] = floatval($string); 128 } 129 } 130 $i++; 131 } 132 $total = count($elements); 133 $number = floatval($number); 134 135 if ($leftBracket == '{' && $rightBracket == '}') 136 { 137 return in_array($number, $elements); 138 } 139 140 $left = false; 141 if ($leftBracket == '[') 142 { 143 $left = $number >= $elements[0]; 144 } 145 else if ($leftBracket == '(') 146 { 147 $left = $number > $elements[0]; 148 } 149 150 $right = false; 151 if ($rightBracket==']') 152 { 153 $right = $number <= $elements[$total - 1]; 154 } 155 else if ($rightBracket == ')') 156 { 157 $right = $number < $elements[$total - 1]; 158 } 159 160 if ($left && $right) 161 { 162 return true; 163 } 164 165 return false; 166 } 167 168 /** 169 * Parse a choice string and get a list of sets and a list of strings corresponding to the sets. 170 * 171 * @param string the string containing the choices 172 * @return array array($sets, $strings) 173 */ 174 public function parse($string) 175 { 176 $n = preg_match_all($this->parse, $string, $matches, PREG_OFFSET_CAPTURE); 177 $sets = array(); 178 foreach ($matches[1] as $match) 179 { 180 $sets[] = $match[0]; 181 } 182 183 $offset = $matches[0]; 184 $strings = array(); 185 for ($i = 0; $i < $n; $i++) 186 { 187 $len = strlen($offset[$i][0]); 188 $begin = $i == 0 ? $len : $offset[$i][1] + $len; 189 $end = $i == $n - 1 ? strlen($string) : $offset[$i + 1][1]; 190 $strings[] = substr($string, $begin, $end - $begin); 191 } 192 193 return array($sets, $strings); 194 } 195 196 /** 197 * For the choice string, and a number, find and return the string that satisfied the set within the choices. 198 * 199 * @param string the choices string. 200 * @param float the number to test. 201 * @return string the choosen string. 202 */ 203 public function format($string, $number) 204 { 205 list($sets, $strings) = $this->parse($string); 206 $total = count($sets); 207 for ($i = 0; $i < $total; $i++) 208 { 209 if ($this->isValid($number, $sets[$i])) 210 { 211 return $strings[$i]; 212 } 213 } 214 215 return false; 216 } 217 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |