first addition of extra rss files needed by rss_client block. templib functionality...
[moodle.git] / rss / class.Atom.php
1 <?php
2 /*
3  * Project:     phAnTOM: a simple Atom parsing class
4  * File:        atom_parse.php includes code for parsing
5  *                              Atom feeds, and returning an Atom object
6  * Author:      Jeremy Ashcraft <ashcraft@13monkeys.com>
7  * Version:             0.1
8  * License:             GPL
9  *
10  * The lastest version of phAnTOM can be obtained from:
11  * http://www.simplog.org
12  *
13  * For questions, help, comments, discussion, etc., please join the
14  * Simplog Atom mailing list:
15  * simplog-atom@lists.sourceforge.net
16  *
17  * This code is based on the MagpieRSS parser v0.52 written
18  * by Kellan Elliott-McCrea <kellan@protest.net> and released under the GPL
19  */
20  
22 /* 
23  * The lastest Atom feed spec is at http://diveintomark.org/public/2003/08/atom02spec.txt
24  *
25  *
26  * RSS/Atom validators are readily available on the web at:
27  * http://feeds.archive.org/validator/
28  *
29  */
31 class Atom {
32         /*
33          * Useage Example:
34          *
35          * $xml = "<?xml version="1.0"......
36          *
37          * $atom = new atom( $xml );
38          *
39          * // print feed title
40          * print $atom->feed['title'];
41          *
42          * // print the title of each entry
43          * foreach ($atom->entries as $entry ) {
44          *        print $entry[title];
45          * }
46          *
47          */
48          
49         var $parser;
50         
51         var $current_item       = array();      // item currently being parsed
52         var $entries            = array();      // collection of parsed items
53         var $feed               = array();      // hash of channel fields
54         
55         var $parent_field       = array('RDF');
56         var $author             = array();
57         var $contributor        = array();
58         var $current_field      = '';
59         var $current_namespace  = false;
60         
61         var $ERROR = '';
62         
63 /*======================================================================*\
64     Function: MagpieRSS
65     Purpose:  Constructor, sets up XML parser,parses source,
66                           and populates object.. 
67         Input:    String containing the RSS to be parsed
68 \*======================================================================*/
69         function Atom ($source) {
70                 
71                 # if PHP xml isn't compiled in, die
72                 #
73                 if (!function_exists('xml_parser_create')) {
74                         $this->error( 'Failed to load PHP\'s XML Extension. ' . 
75                                                   'http://www.php.net/manual/en/ref.xml.php',
76                                                    E_USER_ERROR );
77                 }
78                 
79                 $parser = @xml_parser_create();
80                 
81                 if (!is_resource($parser))
82                 {
83                         $this->error( 'Failed to create an instance of PHP\'s XML parser. ' .
84                                                   'http://www.php.net/manual/en/ref.xml.php',
85                                                   E_USER_ERROR );
86                 }
88                 
89                 $this->parser = $parser;
90                 
91                 # pass in parser, and a reference to this object
92                 # setup handlers
93                 #
94                 xml_set_object( $this->parser, $this );
95                 xml_set_element_handler($this->parser, 'start_element', 'end_element');
96                 xml_set_character_data_handler( $this->parser, 'cdata' ); 
97         
98                 
99                 $status = xml_parse( $this->parser, $source );
100                 
101                 if (! $status ) {
102                         $errorcode = xml_get_error_code( $this->parser );
103                         if ( $errorcode != XML_ERROR_NONE ) {
104                                 $xml_error = xml_error_string( $errorcode );
105                                 $error_line = xml_get_current_line_number($this->parser);
106                                 $error_col = xml_get_current_column_number($this->parser);
107                                 $errormsg = $xml_error .' at line '. $error_line .', column '. $error_col;
109                                 $this->error( $errormsg );
110                         }
111                 }
112                 
113                 xml_parser_free( $this->parser );
114         }
115         
116         function start_element ($p, $element, &$attrs) {
117                 $element        = strtolower( $element );
118                 # check for a namespace, and split if found
119                 #
120                 $namespace      = false;
121                 if ( strpos( $element, ':' ) ) {
122                         list($namespace, $element) = split( ':', $element, 2); 
123                 }
124                 $this->current_field = $element;
125                 if ( $namespace ) {
126                         $this->current_namespace = $namespace;
127                 }
128                 
129                 if ( $element == 'feed' ) {
130                         array_unshift( $this->parent_field, 'feed' );
131                 } else if ( $element == 'items' ) {
132                         array_unshift( $this->parent_field, 'items' );
133                 } else if ( $element == 'entry' ) {
134                         array_unshift( $this->parent_field, 'entry' );
135                 } else if ( $element == 'author' ) {
136                         array_unshift( $this->parent_field, 'author' );
137                 } else if ( $element == 'contributor' ) {
138                         array_unshift( $this->parent_field, 'contributor' );
139                 }
140         }
141         
142         function end_element ($p, $element) {
143                 $element = strtolower($element);
144                                                         
145                 if ( $element == 'entry' ) {    
146                         $this->entries[] = $this->current_item;
147                         $this->current_item = array();
148                         array_shift( $this->parent_field );
149                 } else if ( $element == 'feed' or $element == 'items' or 
150                                  $element == 'author' or $element == 'contributor') {
151                         array_shift( $this->parent_field );
152                 }
153                 
154                 $this->current_field = '';
155                 $this->current_namespace = false;
156         }
157         
158         function cdata ($p, $text) {
159                 # skip item, channel, items first time we see them
160                 #
161                 if ( $this->parent_field[0] == $this->current_field or
162                          ! $this->current_field ) {
163                         return;
164                 } else if ( $this->parent_field[0] == 'feed') {
165                         if ( $this->current_namespace ) {
166                                 $this->append(
167                                         $this->feed[ $this->current_namespace ][ $this->current_field ],
168                                         $text);
169                         } else {
170                                 $this->append($this->feed[ $this->current_field ], $text);
171                         }
172                 
173                 } else if ( $this->parent_field[0] == 'entry' ) {
174                         if ( $this->current_namespace ) {
175                                 $this->append(
176                                         $this->current_item[ $this->current_namespace ][$this->current_field ],
177                                         $text);
178                         } else {
179                                 $this->append(
180                                         $this->current_item[ $this->current_field ],
181                                         $text );
182                         }
183                 } else if ( $this->parent_field[0] == 'author' ) {
184                         if ( $this->current_namespace ) {
185                                 $this->append(
186                                         $this->author[ $this->current_namespace ][ $this->current_field ],
187                                         $text );
188                         } else {
189                                 $this->append(
190                                         $this->author[ $this->current_field ],
191                                         $text );
192                         }
193                 } else if ( $this->parent_field[0] == 'contributor' ) {
194                         if ( $this->current_namespace ) {
195                                 $this->append(
196                                         $this->contributor[ $this->current_namespace ][ $this->current_field ],
197                                         $text );
198                         } else {
199                                 $this->append(
200                                         $this->contributor[ $this->current_field ],
201                                         $text );
202                         }
203                 }
204         }
205         
206         function append (&$str1, $str2='') {
207                 if (!isset($str1) ) {
208                         $str1='';
209                 }
210                 $str1 .= $str2;
211         }
212         
213         function error ($errormsg, $lvl=E_USER_WARNING) {
214                 // append PHP's error message if track_errors enabled
215                 if ( $php_errormsg ) { 
216                         $errormsg .= ' ('. $php_errormsg .')';
217                 }
218                 $this->ERROR = $errormsg;
219                 if ( ATOM_DEBUG ) {
220                         trigger_error( $errormsg, $lvl);                
221                 } else {
222                         error_log( $errormsg, 0);
223                 }
224         }
225                 
227 /*======================================================================*\
228         EVERYTHING BELOW HERE IS FOR DEBUGGING PURPOSES
229 \*======================================================================*/
230         function show_list () {
231                 print '<ol>'."\n";
232                 foreach ($this->entries as $item) {
233                         print '<li>'. $this->show_entry( $item );
234                 }
235                 print '</ol>';
236         }
237         
238         function show_feed () {
239                 print 'feed:<br />';
240                 print '<ul>';
241                 while ( list($key, $value) = each( $this->feed ) ) {
242                         print '<li> '. $key .': '. $value;
243                 }
244                 print '</ul>';
245         }
246         
247         function show_entry ($item) {
248                 print 'entry: '. $item[title];
249                 print '<ul>';
250                 while ( list($key, $value) = each($item) ) {
251                         if ( is_array($value) ) {
252                                 print '<br /><strong>'. $key .'</strong>';
253                                 print '<ul>';
254                                 while ( list( $ns_key, $ns_value) = each( $value ) ) {
255                                         print '<li>'. $ns_key .': '. $ns_value;
256                                 }
257                                 print '</ul>';
258                         } else {
259                                 print '<li> '. $key .': '. $value;
260                         }
261                 }
262                 print '</ul>';
263         }
265 /*======================================================================*\
266         END DEBUGGING FUNCTIONS 
267 \*======================================================================*/
268         
269 } # end class Atom
270 ?>