1: <?php
2: /*
3: You may not change or alter any portion of this comment or credits
4: of supporting developers from this source code or any supporting source code
5: which is considered copyrighted (c) material of the original comment or credit authors.
6:
7: This program is distributed in the hope that it will be useful,
8: but WITHOUT ANY WARRANTY; without even the implied warranty of
9: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10: */
11:
12: namespace Xmf;
13:
14: use Symfony\Component\Yaml\Yaml as VendorYaml;
15:
16: /**
17: * Yaml dump and parse methods
18: *
19: * YAML is a serialization format most useful when human readability
20: * is a consideration. It can be useful for configuration files, as
21: * well as import and export functions.
22: *
23: * This file is a front end for a separate YAML package present in the
24: * vendor directory. The intent is to provide a consistent interface
25: * no mater what underlying library is actually used.
26: *
27: * At present, this class expects the symfony/yaml package.
28: *
29: * @category Xmf\Yaml
30: * @package Xmf
31: * @author Richard Griffith <richard@geekwright.com>
32: * @copyright 2013-2020 XOOPS Project (https://xoops.org)
33: * @license GNU GPL 2.0 or later (https://www.gnu.org/licenses/gpl-2.0.html)
34: * @link https://xoops.org
35: * @see http://www.yaml.org/
36: */
37: class Yaml
38: {
39:
40: /**
41: * Dump an PHP array as a YAML string
42: *
43: * @param mixed $var Variable which will be dumped
44: * @param integer $inline Nesting level where you switch to inline YAML
45: * @param integer $indent Number of spaces to indent for nested nodes
46: *
47: * @return string|bool YAML string or false on error
48: */
49: public static function dump($var, $inline = 4, $indent = 4)
50: {
51: try {
52: $ret = VendorYaml::dump($var, $inline, $indent);
53: } catch (\Exception $e) {
54: static::logError($e);
55: $ret = false;
56: }
57: return $ret;
58: }
59:
60: /**
61: * Load a YAML string into a PHP array
62: *
63: * @param string $yamlString YAML dump string
64: *
65: * @return array|boolean PHP array or false on error
66: */
67: public static function load($yamlString)
68: {
69: try {
70: $ret = VendorYaml::parse($yamlString);
71: } catch (\Exception $e) {
72: static::logError($e);
73: $ret = false;
74: }
75: return $ret;
76: }
77:
78: /**
79: * Read a file containing YAML into a PHP array
80: *
81: * @param string $yamlFile filename of YAML file
82: *
83: * @return array|false PHP array or false on error
84: */
85: public static function read($yamlFile)
86: {
87: if (!file_exists($yamlFile)) {
88: return false;
89: }
90: try {
91: $yamlString = file_get_contents($yamlFile);
92: $ret = VendorYaml::parse($yamlString);
93: } catch (\Exception $e) {
94: static::logError($e);
95: $ret = false;
96: }
97: return $ret;
98: }
99:
100: /**
101: * Save a PHP array as a YAML file
102: *
103: * @param array $var variable which will be dumped
104: * @param string $yamlFile filename of YAML file
105: * @param integer $inline Nesting level where you switch to inline YAML
106: * @param integer $indent Number of spaces to indent for nested nodes
107: *
108: * @return integer|boolean number of bytes written, or false on error
109: */
110: public static function save($var, $yamlFile, $inline = 4, $indent = 4)
111: {
112: try {
113: $yamlString = VendorYaml::dump($var, $inline, $indent);
114: $ret = file_put_contents($yamlFile, $yamlString);
115: } catch (\Exception $e) {
116: static::logError($e);
117: $ret = false;
118: }
119: return $ret;
120: }
121:
122: /**
123: * Dump an PHP array as a YAML string with a php wrapper
124: *
125: * The wrap is a php header that surrounds the yaml with section markers,
126: * '---' and '...' along with php comment markers. The php wrapper keeps the
127: * yaml file contents from being revealed by serving the file directly from
128: * a poorly configured server.
129: *
130: * @param mixed $var Variable which will be dumped
131: * @param integer $inline Nesting level where you switch to inline YAML
132: * @param integer $indent Number of spaces to indent for nested nodes
133: *
134: * @return string|boolean YAML string or false on error
135: */
136: public static function dumpWrapped($var, $inline = 4, $indent = 4)
137: {
138: try {
139: $yamlString = VendorYaml::dump($var, $inline, $indent);
140: $ret = empty($yamlString) ? false : "<?php\n/*\n---\n" . $yamlString . "\n...\n*/\n";
141: } catch (\Exception $e) {
142: static::logError($e);
143: $ret = false;
144: }
145: return $ret;
146: }
147:
148: /**
149: * Load a YAML string with a php wrapper into a PHP array
150: *
151: * The wrap is a php header that surrounds the yaml with section markers,
152: * '---' and '...' along with php comment markers. The php wrapper keeps the
153: * yaml file contents from being revealed by serving the file directly from
154: * a poorly configured server.
155: *
156: * @param string $yamlString YAML dump string
157: *
158: * @return array|boolean PHP array or false on error
159: */
160: public static function loadWrapped($yamlString)
161: {
162: try {
163: $lines = preg_split('/\R/', $yamlString);
164: $count = count($lines);
165: for ($index = $count; --$index > 0;) {
166: if ('...' === $lines[$index]) {
167: array_splice($lines, $index);
168: break;
169: }
170: }
171: $count = count($lines);
172: for ($index = 0; ++$index < $count;) {
173: if ('---' === $lines[$index]) {
174: array_splice($lines, 0, $index);
175: break;
176: }
177: }
178: $unwrapped = implode("\n", $lines);
179: $ret = VendorYaml::parse($unwrapped);
180: } catch (\Exception $e) {
181: static::logError($e);
182: $ret = false;
183: }
184: return $ret;
185: }
186:
187: /**
188: * Read a file containing YAML with a php wrapper into a PHP array
189: *
190: * The wrap is a php header that surrounds the yaml with section markers,
191: * '---' and '...' along with php comment markers. The php wrapper keeps the
192: * yaml file contents from being revealed by serving the file directly from
193: * a poorly configured server.
194: *
195: * @param string $yamlFile filename of YAML file
196: *
197: * @return array|false PHP array or false on error
198: */
199: public static function readWrapped($yamlFile)
200: {
201: if (!file_exists($yamlFile)) {
202: return false;
203: }
204: try {
205: $yamlString = file_get_contents($yamlFile);
206: $ret = static::loadWrapped($yamlString);
207: } catch (\Exception $e) {
208: static::logError($e);
209: $ret = false;
210: }
211: return $ret;
212: }
213:
214: /**
215: * Save a PHP array as a YAML file with a php wrapper
216: *
217: * The wrap is a php header that surrounds the yaml with section markers,
218: * '---' and '...' along with php comment markers. The php wrapper keeps the
219: * yaml file contents from being revealed by serving the file directly from
220: * a poorly configured server.
221: *
222: * @param array $var variable which will be dumped
223: * @param string $yamlFile filename of YAML file
224: * @param integer $inline Nesting level where you switch to inline YAML
225: * @param integer $indent Number of spaces to indent for nested nodes
226: *
227: * @return integer|boolean number of bytes written, or false on error
228: */
229: public static function saveWrapped($var, $yamlFile, $inline = 4, $indent = 4)
230: {
231: try {
232: $yamlString = static::dumpWrapped($var, $inline, $indent);
233: $ret = file_put_contents($yamlFile, $yamlString);
234: } catch (\Exception $e) {
235: static::logError($e);
236: $ret = false;
237: }
238: return $ret;
239: }
240:
241: /**
242: * @param \Exception $e throwable to log
243: */
244: protected static function logError($e)
245: {
246: if (class_exists('Xoops')) {
247: \Xoops::getInstance()->events()->triggerEvent('core.exception', $e);
248: } else {
249: trigger_error($e->getMessage(), E_USER_ERROR);
250: }
251: }
252: }
253: