JOOMLA中国
  • Joomla中国首页
  • 社区
  • 教程
  • 应用市场
  • B计划
Joomla! Framework TM
  • Namespace
  • Class
  • Tree
  • Deprecated

Namespaces

  • Composer
    • Autoload
  • Joomla
    • Application
      • Cli
        • Output
          • Processor
      • Web
    • Data
    • DI
      • Exception
    • Event
    • Filter
    • Input
    • Ldap
    • Registry
      • Format
    • Session
      • Storage
    • String
    • Uri
    • Utilities
  • None
  • PasswordCompat
    • binary
  • PHP
  • Psr
    • Log
  • Symfony
    • Component
      • Yaml
        • Exception
    • Polyfill
      • Util

Classes

  • Ini
  • Json
  • Php
  • Xml
  • Yaml
  1 <?php
  2 /**
  3  * Part of the Joomla Framework Registry Package
  4  *
  5  * @copyright  Copyright (C) 2005 - 2016 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\AbstractRegistryFormat;
 12 use Joomla\Utilities\ArrayHelper;
 13 use stdClass;
 14 
 15 /**
 16  * INI format handler for Registry.
 17  *
 18  * @since  1.0
 19  */
 20 class Ini extends AbstractRegistryFormat
 21 {
 22     /**
 23      * Default options array
 24      *
 25      * @var    array
 26      * @since  1.3.0
 27      */
 28     protected static $options = array(
 29         'supportArrayValues' => false,
 30         'parseBooleanWords'  => false,
 31         'processSections'    => false,
 32     );
 33 
 34     /**
 35      * A cache used by stringToobject.
 36      *
 37      * @var    array
 38      * @since  1.0
 39      */
 40     protected static $cache = array();
 41 
 42     /**
 43      * Converts an object into an INI formatted string
 44      * - Unfortunately, there is no way to have ini values nested further than two
 45      * levels deep.  Therefore we will only go through the first two levels of
 46      * the object.
 47      *
 48      * @param   object  $object   Data source object.
 49      * @param   array   $options  Options used by the formatter.
 50      *
 51      * @return  string  INI formatted string.
 52      *
 53      * @since   1.0
 54      */
 55     public function objectToString($object, $options = array())
 56     {
 57         $options = array_merge(self::$options, $options);
 58 
 59         $local = array();
 60         $global = array();
 61 
 62         $variables = get_object_vars($object);
 63 
 64         $last = count($variables);
 65 
 66         // Assume that the first element is in section
 67         $in_section = 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 (!$in_section)
 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) && $options['supportArrayValues'])
 88                     {
 89                         $assoc = ArrayHelper::isAssociative($v);
 90 
 91                         foreach ($v as $array_key => $item)
 92                         {
 93                             $array_key = ($assoc) ? $array_key : '';
 94                             $local[] = $k . '[' . $array_key . ']=' . $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 (0 != --$last)
105                 {
106                     $local[] = '';
107                 }
108             }
109             elseif (is_array($value) && $options['supportArrayValues'])
110             {
111                 $assoc = ArrayHelper::isAssociative($value);
112 
113                 foreach ($value as $array_key => $item)
114                 {
115                     $array_key = ($assoc) ? $array_key : '';
116                     $global[] = $key . '[' . $array_key . ']=' . $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                 $in_section = 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 = array())
141     {
142         $options = array_merge(self::$options, $options);
143 
144         // Check the memory cache for already processed strings.
145         $hash = md5($data . ':' . (int) $options['processSections']);
146 
147         if (isset(self::$cache[$hash]))
148         {
149             return self::$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                     continue;
185                 }
186             }
187             elseif ($line{0} == '[')
188             {
189                 continue;
190             }
191 
192             // Check that an equal sign exists and is not the first character of the line.
193             if (!strpos($line, '='))
194             {
195                 // Maybe throw exception?
196                 continue;
197             }
198 
199             // Get the key and value for the line.
200             list ($key, $value) = explode('=', $line, 2);
201 
202             // If we have an array item
203             if (substr($key, -1) == ']' && ($open_brace = strpos($key, '[', 1)) !== false)
204             {
205                 if ($options['supportArrayValues'])
206                 {
207                     $array = true;
208                     $array_key = substr($key, $open_brace + 1, -1);
209 
210                     // If we have a multi-dimensional array or malformed key
211                     if (strpos($array_key, '[') !== false || strpos($array_key, ']') !== false)
212                     {
213                         // Maybe throw exception?
214                         continue;
215                     }
216 
217                     $key = substr($key, 0, $open_brace);
218                 }
219                 else
220                 {
221                     continue;
222                 }
223             }
224 
225             // Validate the key.
226             if (preg_match('/[^A-Z0-9_]/i', $key))
227             {
228                 // Maybe throw exception?
229                 continue;
230             }
231 
232             // If the value is quoted then we assume it is a string.
233             $length = strlen($value);
234 
235             if ($length && ($value[0] == '"') && ($value[$length - 1] == '"'))
236             {
237                 // Strip the quotes and Convert the new line characters.
238                 $value = stripcslashes(substr($value, 1, ($length - 2)));
239                 $value = str_replace('\n', "\n", $value);
240             }
241             else
242             {
243                 // If the value is not quoted, we assume it is not a string.
244 
245                 // If the value is 'false' assume boolean false.
246                 if ($value == 'false')
247                 {
248                     $value = false;
249                 }
250                 elseif ($value == 'true')
251                 // If the value is 'true' assume boolean true.
252                 {
253                     $value = true;
254                 }
255                 elseif ($options['parseBooleanWords'] && in_array(strtolower($value), array('yes', 'no')))
256                 // If the value is 'yes' or 'no' and option is enabled assume appropriate boolean
257                 {
258                     $value = (strtolower($value) == 'yes');
259                 }
260                 elseif (is_numeric($value))
261                 // If the value is numeric than it is either a float or int.
262                 {
263                     // If there is a period then we assume a float.
264                     if (strpos($value, '.') !== false)
265                     {
266                         $value = (float) $value;
267                     }
268                     else
269                     {
270                         $value = (int) $value;
271                     }
272                 }
273             }
274 
275             // If a section is set add the key/value to the section, otherwise top level.
276             if ($section)
277             {
278                 if ($array)
279                 {
280                     if (!isset($obj->$section->$key))
281                     {
282                         $obj->$section->$key = array();
283                     }
284 
285                     if (!empty($array_key))
286                     {
287                         $obj->$section->{$key}[$array_key] = $value;
288                     }
289                     else
290                     {
291                         $obj->$section->{$key}[] = $value;
292                     }
293                 }
294                 else
295                 {
296                     $obj->$section->$key = $value;
297                 }
298             }
299             else
300             {
301                 if ($array)
302                 {
303                     if (!isset($obj->$key))
304                     {
305                         $obj->$key = array();
306                     }
307 
308                     if (!empty($array_key))
309                     {
310                         $obj->{$key}[$array_key] = $value;
311                     }
312                     else
313                     {
314                         $obj->{$key}[] = $value;
315                     }
316                 }
317                 else
318                 {
319                     $obj->$key = $value;
320                 }
321             }
322 
323             $array = false;
324         }
325 
326         // Cache the string to save cpu cycles -- thus the world :)
327         self::$cache[$hash] = clone $obj;
328 
329         return $obj;
330     }
331 
332     /**
333      * Method to get a value in an INI format.
334      *
335      * @param   mixed  $value  The value to convert to INI format.
336      *
337      * @return  string  The value in INI format.
338      *
339      * @since   1.0
340      */
341     protected function getValueAsIni($value)
342     {
343         $string = '';
344 
345         switch (gettype($value))
346         {
347             case 'integer':
348             case 'double':
349                 $string = $value;
350                 break;
351 
352             case 'boolean':
353                 $string = $value ? 'true' : 'false';
354                 break;
355 
356             case 'string':
357                 // Sanitize any CRLF characters..
358                 $string = '"' . str_replace(array("\r\n", "\n"), '\\n', $value) . '"';
359                 break;
360         }
361 
362         return $string;
363     }
364 }
365 
Joomla! Framework TM API documentation generated by ApiGen 2.8.0
Joomla!® and Joomla! Framework™ are trademarks of Open Source Matters, Inc. in the United States and other countries.