1+ <?php
2+ /**
3+ * Format class
4+ *
5+ * Help convert between various formats such as XML, JSON, CSV, etc.
6+ *
7+ * @author Phil Sturgeon
8+ * @license http://philsturgeon.co.uk/code/dbad-license
9+ */
10+ class Format {
11+
12+ // Array to convert
13+ protected $ _data = array ();
14+
15+ // View filename
16+ protected $ _from_type = null ;
17+
18+ /**
19+ * Returns an instance of the Format object.
20+ *
21+ * echo Format::factory(array('foo' => 'bar'))->to_xml();
22+ *
23+ * @param mixed general date to be converted
24+ * @param string data format the file was provided in
25+ * @return Factory
26+ */
27+ public static function factory ($ data , $ from_type = null )
28+ {
29+ // Stupid stuff to emulate the "new static()" stuff in this libraries PHP 5.3 equivilent
30+ $ class = __CLASS__ ;
31+ return new $ class ($ data , $ from_type );
32+ }
33+
34+ /**
35+ * Do not use this directly, call factory()
36+ */
37+ public function __construct ($ data = null , $ from_type = null )
38+ {
39+ // If the provided data is already formatted we should probably convert it to an array
40+ if ($ from_type !== null )
41+ {
42+ if (method_exists ($ this , '_from_ ' . $ from_type ))
43+ {
44+ $ data = call_user_func (array ($ this , '_from_ ' . $ from_type ), $ data );
45+ }
46+
47+ else
48+ {
49+ throw new Exception ('Format class does not support conversion from " ' . $ from_type . '". ' );
50+ }
51+ }
52+
53+ $ this ->_data = $ data ;
54+ }
55+
56+ // FORMATING OUTPUT ---------------------------------------------------------
57+
58+ public function to_array ($ data = null )
59+ {
60+ if ($ data === null )
61+ {
62+ $ data = $ this ->_data ;
63+ }
64+
65+ $ array = array ();
66+
67+ foreach ((array ) $ this ->_data as $ key => $ value )
68+ {
69+ if (is_object ($ value ) or is_array ($ value ))
70+ {
71+ $ array [$ key ] = static ::to_array ($ value );
72+ }
73+
74+ else
75+ {
76+ $ array [$ key ] = $ value ;
77+ }
78+ }
79+
80+ return $ array ;
81+ }
82+
83+ // Format XML for output
84+ public function to_xml ($ data = null , $ structure = NULL , $ basenode = 'xml ' )
85+ {
86+ if ($ data == null )
87+ {
88+ $ data = $ this ->_data ;
89+ }
90+
91+ // turn off compatibility mode as simple xml throws a wobbly if you don't.
92+ if (ini_get ('zend.ze1_compatibility_mode ' ) == 1 )
93+ {
94+ ini_set ('zend.ze1_compatibility_mode ' , 0 );
95+ }
96+
97+ if ($ structure == NULL )
98+ {
99+ $ structure = simplexml_load_string ("<?xml version='1.0' encoding='utf-8'?>< $ basenode /> " );
100+ }
101+
102+ // Force it to be something useful
103+ if ( ! is_array ($ data ) AND ! is_object ($ data ))
104+ {
105+ $ data = (array ) $ data ;
106+ }
107+
108+ foreach ($ data as $ key => $ value )
109+ {
110+ // no numeric keys in our xml please!
111+ if (is_numeric ($ key ))
112+ {
113+ // make string key...
114+ //$key = "item_". (string) $key;
115+ $ key = "item " ;
116+ }
117+
118+ // replace anything not alpha numeric
119+ $ key = preg_replace ('/[^a-z_\-0-9]/i ' , '' , $ key );
120+
121+ // if there is another array found recrusively call this function
122+ if (is_array ($ value ) OR is_object ($ value ))
123+ {
124+ $ node = $ structure ->addChild ($ key );
125+ $ this ->to_xml ($ value , $ node , $ basenode );
126+ }
127+ else
128+ {
129+ // Actual boolean values need to be converted to numbers
130+ is_bool ($ value ) AND $ value = (int ) $ value ;
131+
132+ // add single node.
133+ $ value = htmlspecialchars (html_entity_decode ($ value , ENT_QUOTES , 'UTF-8 ' ), ENT_QUOTES , "UTF-8 " );
134+
135+ $ structure ->addChild ($ key , $ value );
136+ }
137+ }
138+
139+ return $ structure ->asXML ();
140+ }
141+
142+ // Format HTML for output
143+ // private function to_html($data = array())
144+ // {
145+ // // Multi-dimentional array
146+ // if (isset($data[0]))
147+ // {
148+ // $headings = array_keys($data[0]);
149+ // }
150+ //
151+ // // Single array
152+ // else
153+ // {
154+ // $headings = array_keys($data);
155+ // $data = array($data);
156+ // }
157+ //
158+ // $this->load->library('table');
159+ //
160+ // $this->table->set_heading($headings);
161+ //
162+ // foreach ($data as &$row)
163+ // {
164+ // $this->table->add_row($row);
165+ // }
166+ //
167+ // return $this->table->generate();
168+ // }
169+
170+ // Format HTML for output
171+ public function to_csv ()
172+ {
173+ $ data = $ this ->_data ;
174+
175+ // Multi-dimentional array
176+ if (isset ($ data [0 ]))
177+ {
178+ $ headings = array_keys ($ data [0 ]);
179+ }
180+
181+ // Single array
182+ else
183+ {
184+ $ headings = array_keys ($ data );
185+ $ data = array ($ data );
186+ }
187+
188+ $ output = implode (', ' , $ headings ).PHP_EOL ;
189+ foreach ($ data as &$ row )
190+ {
191+ $ output .= '" ' .implode ('"," ' , $ row ).'" ' .PHP_EOL ;
192+ }
193+
194+ return $ output ;
195+ }
196+
197+ // Encode as JSON
198+ public function to_json ()
199+ {
200+ return json_encode ($ this ->_data );
201+ }
202+
203+ // Encode as Serialized array
204+ public function to_serialized ()
205+ {
206+ return serialize ($ this ->_data );
207+ }
208+
209+
210+ // Format XML for output
211+ protected function _from_xml ($ string )
212+ {
213+ return (array ) simplexml_load_string ($ string , 'SimpleXMLElement ' , LIBXML_NOCDATA );
214+ }
215+
216+ // Format HTML for output
217+ // This function is DODGY! Not perfect CSV support but works with my REST_Controller
218+ protected function _from_csv ($ string )
219+ {
220+ $ data = array ();
221+
222+ // Splits
223+ $ rows = explode ("\n" , trim ($ string ));
224+ $ headings = explode (', ' , array_shift ($ rows ));
225+ foreach ($ rows as $ row )
226+ {
227+ // The substr removes " from start and end
228+ $ data_fields = explode ('"," ' , trim (substr ($ row , 1 , -1 )));
229+
230+ if (count ($ data_fields ) == count ($ headings ))
231+ {
232+ $ data [] = array_combine ($ headings , $ data_fields );
233+ }
234+ }
235+
236+ return $ data ;
237+ }
238+
239+ // Encode as JSON
240+ private function _from_json ($ string )
241+ {
242+ return json_decode (trim ($ string ));
243+ }
244+
245+ // Encode as Serialized array
246+ private function _from_serialize ($ string )
247+ {
248+ return unserialize (trim ($ string ));
249+ }
250+
251+ }
252+
253+ /* End of file format.php */
0 commit comments