Tutorial Extension  1.0.0
SellerDeck Extensions - Tutorial Extension
Tools.php
1 <?php
2 
3 /**
4  * Tools.php - Contains various string and array helper functions
5  *
6  * @package SellerDeck Extensions
7  *
8  * @author Péter Erdődi
9  * @copyright © SellerDeck Ltd 2015. All rights reserved.
10  */
11 
12 /**
13  * Checks if array is associative
14  *
15  * @param array $array an array
16  * @return bool Is array associative?
17  */
18 function is_assoc($array)
19  {
20  return (bool) count(array_filter(array_keys($array), 'is_string'));
21  }
22 
23 /**
24  * Checks if varible is a string, or array. Array will be imploded to string.
25  *
26  * @param string|array $vData string or an array
27  * @return string original string, or imploded array
28  */
29 function string_or_implode_array($vData)
30  {
31  if (is_array($vData))
32  {
33  return implode(' ', $vData);
34  }
35  return (string) $vData;
36  }
37 
38 /**
39  * Builds XML from array
40  *
41  * @todo Generates tags onlywithout attributes
42  * @param array $aArray An array containing XML nodes
43  * @param string $sRoot XML root tag
44  * @param string $sCustomHeader Custom header tag
45  * @return string XML
46  */
47 function array2xml($aArray, $sRoot = 'root', $sCustomHeader = '<?xml version="1.0" encoding="UTF-8"?>')
48  {
49  $sRootNode = "$sCustomHeader<$sRoot/>";
50  $oXML = new \SimpleXMLElement($sRootNode);
51  array2xml_recursive($aArray, $oXML, null);
52  $sData = $oXML->asXML();
53  return $sData;
54  }
55 
56 /**
57  * Builds XML from array (helper function, recursive part)
58  *
59  * @param array $aArray An array containing XML nodes
60  * @param SimpleXMLElement $oSimpleXMLElement XML root tag
61  * @return void
62  */
63 function array2xml_recursive($aArray, &$oSimpleXMLElement)
64  {
65  foreach ($aArray as $sNodeName => $vValue)
66  {
67  if (is_array($vValue))
68  {
69  if (is_assoc($vValue))
70  {
71  $oXML = $oSimpleXMLElement->addChild($sNodeName);
72  array2xml_recursive($vValue, $oXML);
73  }
74  else
75  {
76  foreach ($vValue as $vValue2)
77  {
78  if (is_array($vValue2))
79  {
80  $oXML = $oSimpleXMLElement->addChild($sNodeName);
81  array2xml_recursive($vValue2, $oXML);
82  }
83  else
84  {
85  $oSimpleXMLElement->addChild($sNodeName, $vValue2);
86  }
87  }
88  }
89  }
90  else
91  {
92  $oSimpleXMLElement->addChild($sNodeName, $vValue);
93  }
94  }
95  }
96 
97 /**
98  * Converts XML string to JSON string
99  *
100  * @param string $sXMLString XML
101  * @return string JSON
102  */
103 function xml2json($sXMLString)
104  {
105  $oXML = simplexml_load_string($sXMLString);
106  $sJSON = json_encode($oXML);
107  return $sJSON;
108  }
109 
110 /**
111  * Converts XML string to PHP array
112  *
113  * @param string $sXMLString XML
114  * @return array
115  */
116 function xml2array($sXMLString)
117  {
118  $sJSON = xml2json($sXMLString);
119  $aArray = json_decode($sJSON, TRUE);
120  return $aArray;
121  }
122 
123 /**
124  * Gets a dot-notated key from an array, with a default value if it does
125  * not exist.
126  *
127  * @param array $array The search array
128  * @param mixed $nKey The dot-notated key or array of keys
129  * @param string $default The default value
130  * @param bool $bCheckEmpty Checks if value is not empty, returns default value, if it is empty
131  * @return mixed
132  */
133 function arr_get($array, $nKey, $default = null, $bCheckEmpty = false)
134  {
135  if (!is_array($array) and ! $array instanceof \ArrayAccess)
136  {
137  return $default;
138 // throw new \InvalidArgumentException('First parameter must be an array or ArrayAccess object.');
139  }
140 
141  if (is_null($nKey))
142  {
143  return $array;
144  }
145 
146  if (is_array($nKey))
147  {
148  $return = array();
149  foreach ($nKey as $k)
150  {
151  $return[$k] = arr_get($array, $k, $default);
152  }
153  return $return;
154  }
155 
156  is_object($nKey) and $nKey = (string) $nKey;
157 
158  if (array_key_exists($nKey, $array))
159  {
160  if ($bCheckEmpty && (empty($array[$nKey]) || (is_string($array[$nKey]) && empty(trim($array[$nKey])))))
161  {
162  return $default;
163  }
164  return $array[$nKey];
165  }
166 
167  foreach (explode('.', $nKey) as $nKey_part)
168  {
169  if ((is_a($array, 'ArrayAccess') and isset($array[$nKey_part])) === false)
170  {
171  if (!is_array($array) or ! array_key_exists($nKey_part, $array))
172  {
173  return $default;
174  }
175  }
176 
177  $array = $array[$nKey_part];
178  }
179 
180  if ($bCheckEmpty && empty($array))
181  {
182  return $default;
183  }
184  return $array;
185  }
186 
187 /**
188  * Checks if string starts with prefix
189  *
190  * @param string $sHaystack The string to search in
191  * @param string $sNeedle The string to search for
192  * @return bool String starts with prefix
193  */
194 function starts_with($sHaystack, $sNeedle)
195  {
196 // search backwards starting from haystack length characters from the end
197  return $sNeedle === "" || strrpos($sHaystack, $sNeedle, -strlen($sHaystack)) !== FALSE;
198  }
199 
200 /**
201  * Checks if string ends with suffix
202  *
203  * @param string $sHaystack The string to search in
204  * @param string $sNeedle The string to search for
205  * @return bool String ends with suffix
206  */
207 function ends_with($sHaystack, $sNeedle)
208  {
209 // search forward starting from end minus needle length characters
210  return $sNeedle === "" || (($sTemp = strlen($sHaystack) - strlen($sNeedle)) >= 0 && strpos($sHaystack, $sNeedle, $sTemp) !== FALSE);
211  }
212 
213 /**
214  * Removes string prefix
215  *
216  * @param string $sStr The string to search in
217  * @param string $sPrefix Prefix
218  * @return string String without prefix
219  */
220 function remove_prefix($sStr, $sPrefix)
221  {
222  return substr($sStr, strlen($sPrefix));
223  }
224 
225 /**
226  * Removes string prefix
227  *
228  * @param string $sStr The string to search in
229  * @param string $sPrefix Prefix
230  * @return string String without prefix
231  */
232 function remove_suffix($sStr, $sPrefix)
233  {
234  return substr($sStr, 0, -1 * strlen($sPrefix));
235  }
236 
237 /**
238  * Converts seconds to text time
239  *
240  * @param int $nSeconds Seconds
241  * @return string Time in text
242  */
243 function seconds_to_time($nSeconds)
244  {
245  $oZeroDT = new DateTime("@0");
246  $oSecondsDT = new DateTime("@$nSeconds");
247  return $oZeroDT->diff($oSecondsDT)->format('%a days, %h hours, %i minutes and %s seconds');
248  }
249 
250 /**
251  * load_config - Loads configuration PHP file into a variable
252  *
253  * @param string $sFileName PHP file name to load
254  * @param function $fErrorCallback Callback function, called in case of Error
255  * @return array Configuration array
256  */
257 function load_config($sFileName, $fErrorCallback = null)
258  {
259  if (file_exists($sFileName))
260  {
261  $aConfigData = include $sFileName;
262  return $aConfigData;
263  }
264  elseif (is_callable($fErrorCallback))
265  {
266  call_user_func($fErrorCallback);
267  }
268  return [];
269  }
270 
271 /**
272  * load_view - Loads a PHP file contents as string
273  *
274  * @param string $sFileName PHP file name to load
275  * @param array $aVariables Associative array of Variables used in the view, key values will be variable names.
276  * @return string File contents
277  */
278 function load_view($sFileName, $aVariables = [])
279  {
280  ob_start();
281  $sContents = "";
282  if (file_exists($sFileName))
283  {
284  extract($aVariables);
285  include $sFileName;
286  $sContents = ob_get_contents();
287  }
288  ob_end_clean();
289  return $sContents;
290  }
291 
292 /**
293  * Simple detection of html tags: text has < or >
294  *
295  * @return bool Has < or >
296  */
297 function has_html($sText)
298  {
299  return strpos($sText, '<') !== false || strpos($sText, '>') !== false;
300  }
301 
302 /**
303  * Gets MAC address
304  *
305  * @return string MAC address
306  */
307 function get_mac()
308  {
309  ob_start(); // Turn on output buffering
310  system('ipconfig /all'); //Execute external program to display output
311  $sConsoleOutput = ob_get_contents(); // Capture the output into a variable
312  ob_clean(); // Clean (erase) the output buffer
313  $sMAC = substr($sConsoleOutput, (strpos($sConsoleOutput, "Physical") + 36), 17); // Get Physical Address
314  return $sMAC;
315  }
316 
317 /**
318  * Quotes INI value
319  *
320  * @param mixed $vValue Value
321  * @return string Quoted value
322  */
323 function quote_ini_value($vValue)
324  {
325  if (is_numeric($vValue))
326  {
327  return $vValue . "\n";
328  }
329  return "\"" . $vValue . "\"\n";
330  }
331 
332 /**
333  * Writes INI File
334  *
335  * @param array $aSettings Settings associative array
336  * @param string $sPath Path
337  * @param bool $bHasSections Has Sections
338  * @return string MAC address
339  */
340 function write_ini_file($aSettings, $sPath, $bHasSections = FALSE)
341  {
342  $sContent = "";
343  if ($bHasSections)
344  {
345  foreach ($aSettings as $nKey => $vElement)
346  {
347  $sContent .= "[" . $nKey . "]\n";
348  foreach ($vElement as $nKey2 => $vElement2)
349  {
350  if (is_array($vElement2))
351  {
352  for ($i = 0; $i < count($vElement2); $i++)
353  {
354  $sContent .= $nKey2 . "[] = " . quote_ini_value($vElement2[$i]);
355  }
356  }
357  else if ($vElement2 == "")
358  $sContent .= $nKey2 . " = \n";
359  else
360  $sContent .= $nKey2 . " = " . quote_ini_value($vElement2);
361  }
362  }
363  }
364  else
365  {
366  foreach ($aSettings as $nKey => $vElement)
367  {
368  if (is_array($vElement))
369  {
370  for ($i = 0; $i < count($vElement); $i++)
371  {
372  $sContent .= $nKey . "[] = " . quote_ini_value($vElement[$i]);
373  }
374  }
375  else if ($vElement == "")
376  $sContent .= $nKey . " = \n";
377  else
378  $sContent .= $nKey . " = " . quote_ini_value($vElement);
379  }
380  }
381 
382  if (!$oHandle = fopen($sPath, 'w'))
383  {
384  return false;
385  }
386 
387  $bSuccess = fwrite($oHandle, $sContent);
388  fclose($oHandle);
389 
390  return $bSuccess;
391  }
392 
393 /**
394  * sse_header - Sets Header for Data Stream
395  *
396  * @access public
397  * @return void
398  */
399 function sse_header()
400  {
401  header("Content-Type: text/event-stream");
402  header("Cache-Control: no-cache");
403  header("Connection: keep-alive");
404  }
405 
406 /**
407  * sse_message - Sends Stream Message
408  *
409  * @access public
410  * @return void
411  */
412 function sse_message($vData)
413  {
414  if (is_array($vData))
415  {
416  echo "data: " . json_encode($vData) . "\n";
417  }
418  else
419  {
420  echo "data: $vData\n";
421  }
422  echo "\n";
423  ob_flush();
424  flush();
425  }
426 
427 /**
428  * sse_close - Sends Stream Close
429  *
430  * @access public
431  * @return void
432  */
433 function sse_close()
434  {
435  sse_message('CLOSE');
436  }