PageRenderTime 57ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/fuel/category_tool/fuel/core/classes/format.php

https://github.com/connvoi/dev
PHP | 532 lines | 432 code | 29 blank | 71 comment | 20 complexity | eeebc49b450186c66d6fac620f895e85 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause
  1. <?php
  2. /**
  3. * Part of the Fuel framework.
  4. *
  5. * @package Fuel
  6. * @version 1.0
  7. * @author Fuel Development Team
  8. * @license MIT License
  9. * @copyright 2010 - 2012 Fuel Development Team
  10. * @link http://fuelphp.com
  11. */
  12. namespace Fuel\Core;
  13. /**
  14. * Format class
  15. *
  16. * Help convert between various formats such as XML, JSON, CSV, etc.
  17. *
  18. * @package Fuel
  19. * @category Core
  20. * @author Fuel Development Team
  21. * @copyright 2010 - 2012 Fuel Development Team
  22. * @link http://docs.fuelphp.com/classes/format.html
  23. */
  24. class Format
  25. {
  26. /**
  27. * @var array|mixed input to convert
  28. */
  29. protected $_data = array();
  30. /**
  31. * Returns an instance of the Format object.
  32. *
  33. * echo Format::forge(array('foo' => 'bar'))->to_xml();
  34. *
  35. * @param mixed general date to be converted
  36. * @param string data format the file was provided in
  37. * @return Format
  38. */
  39. public static function forge($data = null, $from_type = null)
  40. {
  41. return new static($data, $from_type);
  42. }
  43. /**
  44. * Do not use this directly, call forge()
  45. */
  46. public function __construct($data = null, $from_type = null)
  47. {
  48. // If the provided data is already formatted we should probably convert it to an array
  49. if ($from_type !== null)
  50. {
  51. if (method_exists($this, '_from_' . $from_type))
  52. {
  53. $data = call_user_func(array($this, '_from_' . $from_type), $data);
  54. }
  55. else
  56. {
  57. throw new \FuelException('Format class does not support conversion from "' . $from_type . '".');
  58. }
  59. }
  60. $this->_data = $data;
  61. }
  62. // FORMATING OUTPUT ---------------------------------------------------------
  63. /**
  64. * To array conversion
  65. *
  66. * Goes through the input and makes sure everything is either a scalar value or array
  67. *
  68. * @param mixed $data
  69. * @return array
  70. */
  71. public function to_array($data = null)
  72. {
  73. if ($data === null)
  74. {
  75. $data = $this->_data;
  76. }
  77. $array = array();
  78. if (is_object($data) and ! $data instanceof \Iterator)
  79. {
  80. $data = get_object_vars($data);
  81. }
  82. if (empty($data))
  83. {
  84. return array();
  85. }
  86. foreach ($data as $key => $value)
  87. {
  88. if (is_object($value) or is_array($value))
  89. {
  90. $array[$key] = $this->to_array($value);
  91. }
  92. else
  93. {
  94. $array[$key] = $value;
  95. }
  96. }
  97. return $array;
  98. }
  99. /**
  100. * To XML conversion
  101. *
  102. * @param mixed $data
  103. * @param null $structure
  104. * @param null|string $basenode
  105. * @return string
  106. */
  107. public function to_xml($data = null, $structure = null, $basenode = 'xml')
  108. {
  109. if ($data == null)
  110. {
  111. $data = $this->_data;
  112. }
  113. // turn off compatibility mode as simple xml throws a wobbly if you don't.
  114. if (ini_get('zend.ze1_compatibility_mode') == 1)
  115. {
  116. ini_set('zend.ze1_compatibility_mode', 0);
  117. }
  118. if ($structure == null)
  119. {
  120. $structure = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><$basenode />");
  121. }
  122. // Force it to be something useful
  123. if ( ! is_array($data) and ! is_object($data))
  124. {
  125. $data = (array) $data;
  126. }
  127. foreach ($data as $key => $value)
  128. {
  129. // no numeric keys in our xml please!
  130. if (is_numeric($key))
  131. {
  132. // make string key...
  133. $key = (\Inflector::singularize($basenode) != $basenode) ? \Inflector::singularize($basenode) : 'item';
  134. }
  135. // replace anything not alpha numeric
  136. $key = preg_replace('/[^a-z_\-0-9]/i', '', $key);
  137. // if there is another array found recrusively call this function
  138. if (is_array($value) or is_object($value))
  139. {
  140. $node = $structure->addChild($key);
  141. // recursive call if value is not empty
  142. if( ! empty($value))
  143. {
  144. $this->to_xml($value, $node, $key);
  145. }
  146. }
  147. else
  148. {
  149. // add single node.
  150. $value = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, "UTF-8");
  151. $structure->addChild($key, $value);
  152. }
  153. }
  154. // pass back as string. or simple xml object if you want!
  155. return $structure->asXML();
  156. }
  157. /**
  158. * To CSV conversion
  159. *
  160. * @param mixed $data
  161. * @return string
  162. */
  163. public function to_csv($data = null)
  164. {
  165. if ($data === null)
  166. {
  167. $data = $this->_data;
  168. }
  169. // Multi-dimentional array
  170. if (is_array($data) and isset($data[0]))
  171. {
  172. if (\Arr::is_assoc($data[0]))
  173. {
  174. $headings = array_keys($data[0]);
  175. }
  176. else
  177. {
  178. $headings = array_shift($data);
  179. }
  180. }
  181. // Single array
  182. else
  183. {
  184. $headings = array_keys((array) $data);
  185. $data = array($data);
  186. }
  187. $output = implode(',', $headings) . "\n";
  188. foreach ($data as &$row)
  189. {
  190. $output .= '"' . implode('","', (array) $row) . "\"\n";
  191. }
  192. return rtrim($output, "\n");
  193. }
  194. /**
  195. * To JSON conversion
  196. *
  197. * @param mixed $data
  198. * @param bool wether to make the json pretty
  199. * @return string
  200. */
  201. public function to_json($data = null, $pretty = false)
  202. {
  203. if ($data == null)
  204. {
  205. $data = $this->_data;
  206. }
  207. // To allow exporting ArrayAccess objects like Orm\Model instances they need to be
  208. // converted to an array first
  209. $data = (is_array($data) or is_object($data)) ? $this->to_array($data) : $data;
  210. return $pretty ? static::pretty_json($data) : json_encode($data);
  211. }
  212. /**
  213. * To JSONP conversion
  214. *
  215. * @param mixed $data
  216. * @param bool wether to make the json pretty
  217. * @return string
  218. */
  219. public function to_jsonp($data = null, $pretty = false)
  220. {
  221. $callback = \Input::param('callback');
  222. is_null($callback) and $callback = 'response';
  223. return $callback.'('.$this->to_json($data, $pretty).')';
  224. }
  225. /**
  226. * Serialize
  227. *
  228. * @param mixed $data
  229. * @return string
  230. */
  231. public function to_serialized($data = null)
  232. {
  233. if ($data == null)
  234. {
  235. $data = $this->_data;
  236. }
  237. return serialize($data);
  238. }
  239. /**
  240. * Return as a string representing the PHP structure
  241. *
  242. * @param mixed $data
  243. * @return string
  244. */
  245. public function to_php($data = null)
  246. {
  247. if ($data == null)
  248. {
  249. $data = $this->_data;
  250. }
  251. return var_export($data, true);
  252. }
  253. /**
  254. * Convert to YAML
  255. *
  256. * @param mixed $data
  257. * @return string
  258. */
  259. public function to_yaml($data = null)
  260. {
  261. if ($data == null)
  262. {
  263. $data = $this->_data;
  264. }
  265. if ( ! function_exists('spyc_load'))
  266. {
  267. import('spyc/spyc', 'vendor');
  268. }
  269. return \Spyc::YAMLDump($data);
  270. }
  271. /**
  272. * Import XML data
  273. *
  274. * @param string $string
  275. * @return array
  276. */
  277. protected function _from_xml($string)
  278. {
  279. $_arr = is_string($string) ? simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA) : $string;
  280. $arr = array();
  281. // Convert all objects SimpleXMLElement to array recursively
  282. foreach ((array)$_arr as $key => $val)
  283. {
  284. $arr[$key] = (is_array($val) or is_object($val)) ? $this->_from_xml($val) : $val;
  285. }
  286. return $arr;
  287. }
  288. /**
  289. * Import YAML data
  290. *
  291. * @param string $string
  292. * @return array
  293. */
  294. protected function _from_yaml($string)
  295. {
  296. if ( ! function_exists('spyc_load'))
  297. {
  298. import('spyc/spyc', 'vendor');
  299. }
  300. return \Spyc::YAMLLoadString($string);
  301. }
  302. /**
  303. * Import CSV data
  304. *
  305. * @param string $string
  306. * @return array
  307. */
  308. protected function _from_csv($string)
  309. {
  310. $data = array();
  311. // Splits
  312. $rows = explode("\n", trim($string));
  313. // TODO: This means any headers with , will be split, but this is less likley thay a value containing it
  314. $headings = array_map(
  315. function($value)
  316. {
  317. return trim($value, '"');
  318. },
  319. explode(',', array_shift($rows))
  320. );
  321. $join_row = null;
  322. foreach ($rows as $row)
  323. {
  324. // Check for odd numer of double quotes
  325. while (substr_count($row, '"') % 2)
  326. {
  327. // They have a line start to join onto
  328. if ($join_row !== null)
  329. {
  330. // Lets stick this row onto a new line after the existing row, and see what happens
  331. $row = $join_row."\n".$row;
  332. // Did that fix it?
  333. if (substr_count($row, '"') % 2)
  334. {
  335. // Nope, lets try adding the next line
  336. continue 2;
  337. }
  338. else
  339. {
  340. // Yep, lets kill the join row.
  341. $join_row = null;
  342. }
  343. }
  344. // Lets start a new "join line"
  345. else
  346. {
  347. $join_row = $row;
  348. // Lets bust outta this join, and go to the next row (foreach)
  349. continue 2;
  350. }
  351. }
  352. // If present, remove the " from start and end
  353. substr($row, 0, 1) === '"' and $row = substr($row,1);
  354. substr($row, -1) === '"' and $row = substr($row,0,-1);
  355. // Extract the fields from the row
  356. $data_fields = explode('","', $row);
  357. if (count($data_fields) == count($headings))
  358. {
  359. $data[] = array_combine($headings, $data_fields);
  360. }
  361. }
  362. return $data;
  363. }
  364. /**
  365. * Import JSON data
  366. *
  367. * @param string $string
  368. * @return mixed
  369. */
  370. private function _from_json($string)
  371. {
  372. return json_decode(trim($string));
  373. }
  374. /**
  375. * Import Serialized data
  376. *
  377. * @param string $string
  378. * @return mixed
  379. */
  380. private function _from_serialize($string)
  381. {
  382. return unserialize(trim($string));
  383. }
  384. /**
  385. * Makes json pretty the json output.
  386. * Barrowed from http://www.php.net/manual/en/function.json-encode.php#80339
  387. *
  388. * @param string $json json encoded array
  389. * @return string|false pretty json output or false when the input was not valid
  390. */
  391. protected static function pretty_json($data)
  392. {
  393. $json = json_encode($data);
  394. if ( ! $json)
  395. {
  396. return false;
  397. }
  398. $tab = "\t";
  399. $newline = "\n";
  400. $new_json = "";
  401. $indent_level = 0;
  402. $in_string = false;
  403. $len = strlen($json);
  404. for ($c = 0; $c < $len; $c++)
  405. {
  406. $char = $json[$c];
  407. switch($char)
  408. {
  409. case '{':
  410. case '[':
  411. if ( ! $in_string)
  412. {
  413. $new_json .= $char.$newline.str_repeat($tab, $indent_level+1);
  414. $indent_level++;
  415. }
  416. else
  417. {
  418. $new_json .= $char;
  419. }
  420. break;
  421. case '}':
  422. case ']':
  423. if ( ! $in_string)
  424. {
  425. $indent_level--;
  426. $new_json .= $newline.str_repeat($tab, $indent_level).$char;
  427. }
  428. else
  429. {
  430. $new_json .= $char;
  431. }
  432. break;
  433. case ',':
  434. if ( ! $in_string)
  435. {
  436. $new_json .= ','.$newline.str_repeat($tab, $indent_level);
  437. }
  438. else
  439. {
  440. $new_json .= $char;
  441. }
  442. break;
  443. case ':':
  444. if ( ! $in_string)
  445. {
  446. $new_json .= ': ';
  447. }
  448. else
  449. {
  450. $new_json .= $char;
  451. }
  452. break;
  453. case '"':
  454. if ($c > 0 and $json[$c-1] !== '\\')
  455. {
  456. $in_string = ! $in_string;
  457. }
  458. default:
  459. $new_json .= $char;
  460. break;
  461. }
  462. }
  463. return $new_json;
  464. }
  465. }