[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Part of the Joomla Framework Registry Package 4 * 5 * @copyright Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. 6 * @license GNU General Public License version 2 or later; see LICENSE 7 */ 8 9 namespace Joomla\Registry\Format; 10 11 use Joomla\Registry\FormatInterface; 12 use Joomla\Utilities\ArrayHelper; 13 14 /** 15 * INI format handler for Registry. 16 * 17 * @since 1.0 18 */ 19 class Ini implements FormatInterface 20 { 21 /** 22 * Default options array 23 * 24 * @var array 25 * @since 1.3.0 26 */ 27 protected static $options = [ 28 'supportArrayValues' => false, 29 'parseBooleanWords' => false, 30 'processSections' => false, 31 ]; 32 33 /** 34 * A cache used by stringToObject. 35 * 36 * @var array 37 * @since 1.0 38 */ 39 protected static $cache = []; 40 41 /** 42 * Converts an object into an INI formatted string 43 * - Unfortunately, there is no way to have ini values nested further than two 44 * levels deep. Therefore we will only go through the first two levels of 45 * the object. 46 * 47 * @param object $object Data source object. 48 * @param array $options Options used by the formatter. 49 * 50 * @return string INI formatted string. 51 * 52 * @since 1.0 53 */ 54 public function objectToString($object, array $options = []) 55 { 56 $options = array_merge(static::$options, $options); 57 $supportArrayValues = $options['supportArrayValues']; 58 59 $local = []; 60 $global = []; 61 62 $variables = get_object_vars($object); 63 64 $last = \count($variables); 65 66 // Assume that the first element is in section 67 $inSection = true; 68 69 // Iterate over the object to set the properties. 70 foreach ($variables as $key => $value) 71 { 72 // If the value is an object then we need to put it in a local section. 73 if (\is_object($value)) 74 { 75 // Add an empty line if previous string wasn't in a section 76 if (!$inSection) 77 { 78 $local[] = ''; 79 } 80 81 // Add the section line. 82 $local[] = '[' . $key . ']'; 83 84 // Add the properties for this section. 85 foreach (get_object_vars($value) as $k => $v) 86 { 87 if (\is_array($v) && $supportArrayValues) 88 { 89 $assoc = ArrayHelper::isAssociative($v); 90 91 foreach ($v as $arrayKey => $item) 92 { 93 $arrayKey = $assoc ? $arrayKey : ''; 94 $local[] = $k . '[' . $arrayKey . ']=' . $this->getValueAsIni($item); 95 } 96 } 97 else 98 { 99 $local[] = $k . '=' . $this->getValueAsIni($v); 100 } 101 } 102 103 // Add empty line after section if it is not the last one 104 if (--$last !== 0) 105 { 106 $local[] = ''; 107 } 108 } 109 elseif (\is_array($value) && $supportArrayValues) 110 { 111 $assoc = ArrayHelper::isAssociative($value); 112 113 foreach ($value as $arrayKey => $item) 114 { 115 $arrayKey = $assoc ? $arrayKey : ''; 116 $global[] = $key . '[' . $arrayKey . ']=' . $this->getValueAsIni($item); 117 } 118 } 119 else 120 { 121 // Not in a section so add the property to the global array. 122 $global[] = $key . '=' . $this->getValueAsIni($value); 123 $inSection = false; 124 } 125 } 126 127 return implode("\n", array_merge($global, $local)); 128 } 129 130 /** 131 * Parse an INI formatted string and convert it into an object. 132 * 133 * @param string $data INI formatted string to convert. 134 * @param array $options An array of options used by the formatter, or a boolean setting to process sections. 135 * 136 * @return object Data object. 137 * 138 * @since 1.0 139 */ 140 public function stringToObject($data, array $options = []) 141 { 142 $options = array_merge(static::$options, $options); 143 144 // Check the memory cache for already processed strings. 145 $hash = md5($data . ':' . (int) $options['processSections']); 146 147 if (isset(static::$cache[$hash])) 148 { 149 return static::$cache[$hash]; 150 } 151 152 // If no lines present just return the object. 153 if (empty($data)) 154 { 155 return new \stdClass; 156 } 157 158 $obj = new \stdClass; 159 $section = false; 160 $array = false; 161 $lines = explode("\n", $data); 162 163 // Process the lines. 164 foreach ($lines as $line) 165 { 166 // Trim any unnecessary whitespace. 167 $line = trim($line); 168 169 // Ignore empty lines and comments. 170 if (empty($line) || ($line[0] === ';')) 171 { 172 continue; 173 } 174 175 if ($options['processSections']) 176 { 177 $length = \strlen($line); 178 179 // If we are processing sections and the line is a section add the object and continue. 180 if ($line[0] === '[' && ($line[$length - 1] === ']')) 181 { 182 $section = substr($line, 1, $length - 2); 183 $obj->$section = new \stdClass; 184 185 continue; 186 } 187 } 188 elseif ($line[0] === '[') 189 { 190 continue; 191 } 192 193 // Check that an equal sign exists and is not the first character of the line. 194 if (!strpos($line, '=')) 195 { 196 // Maybe throw exception? 197 continue; 198 } 199 200 // Get the key and value for the line. 201 list($key, $value) = explode('=', $line, 2); 202 203 // If we have an array item 204 if (substr($key, -1) === ']' && ($openBrace = strpos($key, '[', 1)) !== false) 205 { 206 if ($options['supportArrayValues']) 207 { 208 $array = true; 209 $arrayKey = substr($key, $openBrace + 1, -1); 210 211 // If we have a multi-dimensional array or malformed key 212 if (strpos($arrayKey, '[') !== false || strpos($arrayKey, ']') !== false) 213 { 214 // Maybe throw exception? 215 continue; 216 } 217 218 $key = substr($key, 0, $openBrace); 219 } 220 else 221 { 222 continue; 223 } 224 } 225 226 // Validate the key. 227 if (preg_match('/[^A-Z0-9_]/i', $key)) 228 { 229 // Maybe throw exception? 230 continue; 231 } 232 233 // If the value is quoted then we assume it is a string. 234 $length = \strlen($value); 235 236 if ($length && ($value[0] === '"') && ($value[$length - 1] === '"')) 237 { 238 // Strip the quotes and Convert the new line characters. 239 $value = stripcslashes(substr($value, 1, $length - 2)); 240 $value = str_replace('\n', "\n", $value); 241 } 242 else 243 { 244 // If the value is not quoted, we assume it is not a string. 245 246 // If the value is 'false' assume boolean false. 247 if ($value === 'false') 248 { 249 $value = false; 250 } 251 elseif ($value === 'true') 252 { 253 // If the value is 'true' assume boolean true. 254 $value = true; 255 } 256 elseif ($options['parseBooleanWords'] && \in_array(strtolower($value), ['yes', 'no'], true)) 257 { 258 // If the value is 'yes' or 'no' and option is enabled assume appropriate boolean 259 $value = (strtolower($value) === 'yes'); 260 } 261 elseif (is_numeric($value)) 262 { 263 // If the value is numeric than it is either a float or int. 264 // If there is a period then we assume a float. 265 if (strpos($value, '.') !== false) 266 { 267 $value = (float) $value; 268 } 269 else 270 { 271 $value = (int) $value; 272 } 273 } 274 } 275 276 // If a section is set add the key/value to the section, otherwise top level. 277 if ($section) 278 { 279 if ($array) 280 { 281 if (!isset($obj->$section->$key)) 282 { 283 $obj->$section->$key = []; 284 } 285 286 if (!empty($arrayKey)) 287 { 288 $obj->$section->{$key}[$arrayKey] = $value; 289 } 290 else 291 { 292 $obj->$section->{$key}[] = $value; 293 } 294 } 295 else 296 { 297 $obj->$section->$key = $value; 298 } 299 } 300 else 301 { 302 if ($array) 303 { 304 if (!isset($obj->$key)) 305 { 306 $obj->$key = []; 307 } 308 309 if (!empty($arrayKey)) 310 { 311 $obj->{$key}[$arrayKey] = $value; 312 } 313 else 314 { 315 $obj->{$key}[] = $value; 316 } 317 } 318 else 319 { 320 $obj->$key = $value; 321 } 322 } 323 324 $array = false; 325 } 326 327 // Cache the string to save cpu cycles -- thus the world :) 328 static::$cache[$hash] = clone $obj; 329 330 return $obj; 331 } 332 333 /** 334 * Method to get a value in an INI format. 335 * 336 * @param mixed $value The value to convert to INI format. 337 * 338 * @return string The value in INI format. 339 * 340 * @since 1.0 341 */ 342 protected function getValueAsIni($value) 343 { 344 $string = ''; 345 346 switch (\gettype($value)) 347 { 348 case 'integer': 349 case 'double': 350 $string = $value; 351 352 break; 353 354 case 'boolean': 355 $string = $value ? 'true' : 'false'; 356 357 break; 358 359 case 'string': 360 // Sanitize any CRLF characters.. 361 $string = '"' . str_replace(["\r\n", "\n"], '\\n', $value) . '"'; 362 363 break; 364 } 365 366 return $string; 367 } 368 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |