Ini.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Config\Writer;
  10. use Zend\Config\Exception;
  11. class Ini extends AbstractWriter
  12. {
  13. /**
  14. * Separator for nesting levels of configuration data identifiers.
  15. *
  16. * @var string
  17. */
  18. protected $nestSeparator = '.';
  19. /**
  20. * If true the INI string is rendered in the global namespace without
  21. * sections.
  22. *
  23. * @var bool
  24. */
  25. protected $renderWithoutSections = false;
  26. /**
  27. * Set nest separator.
  28. *
  29. * @param string $separator
  30. * @return self
  31. */
  32. public function setNestSeparator($separator)
  33. {
  34. $this->nestSeparator = $separator;
  35. return $this;
  36. }
  37. /**
  38. * Get nest separator.
  39. *
  40. * @return string
  41. */
  42. public function getNestSeparator()
  43. {
  44. return $this->nestSeparator;
  45. }
  46. /**
  47. * Set if rendering should occur without sections or not.
  48. *
  49. * If set to true, the INI file is rendered without sections completely
  50. * into the global namespace of the INI file.
  51. *
  52. * @param bool $withoutSections
  53. * @return Ini
  54. */
  55. public function setRenderWithoutSectionsFlags($withoutSections)
  56. {
  57. $this->renderWithoutSections = (bool) $withoutSections;
  58. return $this;
  59. }
  60. /**
  61. * Return whether the writer should render without sections.
  62. *
  63. * @return bool
  64. */
  65. public function shouldRenderWithoutSections()
  66. {
  67. return $this->renderWithoutSections;
  68. }
  69. /**
  70. * processConfig(): defined by AbstractWriter.
  71. *
  72. * @param array $config
  73. * @return string
  74. */
  75. public function processConfig(array $config)
  76. {
  77. $iniString = '';
  78. if ($this->shouldRenderWithoutSections()) {
  79. $iniString .= $this->addBranch($config);
  80. } else {
  81. $config = $this->sortRootElements($config);
  82. foreach ($config as $sectionName => $data) {
  83. if (!is_array($data)) {
  84. $iniString .= $sectionName
  85. . ' = '
  86. . $this->prepareValue($data)
  87. . "\n";
  88. } else {
  89. $iniString .= '[' . $sectionName . ']' . "\n"
  90. . $this->addBranch($data)
  91. . "\n";
  92. }
  93. }
  94. }
  95. return $iniString;
  96. }
  97. /**
  98. * Add a branch to an INI string recursively.
  99. *
  100. * @param array $config
  101. * @param array $parents
  102. * @return string
  103. */
  104. protected function addBranch(array $config, $parents = array())
  105. {
  106. $iniString = '';
  107. foreach ($config as $key => $value) {
  108. $group = array_merge($parents, array($key));
  109. if (is_array($value)) {
  110. $iniString .= $this->addBranch($value, $group);
  111. } else {
  112. $iniString .= implode($this->nestSeparator, $group)
  113. . ' = '
  114. . $this->prepareValue($value)
  115. . "\n";
  116. }
  117. }
  118. return $iniString;
  119. }
  120. /**
  121. * Prepare a value for INI.
  122. *
  123. * @param mixed $value
  124. * @return string
  125. * @throws Exception\RuntimeException
  126. */
  127. protected function prepareValue($value)
  128. {
  129. if (is_int($value) || is_float($value)) {
  130. return $value;
  131. } elseif (is_bool($value)) {
  132. return ($value ? 'true' : 'false');
  133. } elseif (false === strpos($value, '"')) {
  134. return '"' . $value . '"';
  135. } else {
  136. throw new Exception\RuntimeException('Value can not contain double quotes');
  137. }
  138. }
  139. /**
  140. * Root elements that are not assigned to any section needs to be on the
  141. * top of config.
  142. *
  143. * @param array $config
  144. * @return array
  145. */
  146. protected function sortRootElements(array $config)
  147. {
  148. $sections = array();
  149. // Remove sections from config array.
  150. foreach ($config as $key => $value) {
  151. if (is_array($value)) {
  152. $sections[$key] = $value;
  153. unset($config[$key]);
  154. }
  155. }
  156. // Read sections to the end.
  157. foreach ($sections as $key => $value) {
  158. $config[$key] = $value;
  159. }
  160. return $config;
  161. }
  162. }