1<?php
2/* author: alice@muc.ccc.de
3 */
4if (!defined('DOKU_INC')) die();
5if (!defined('DOKU_LF')) define('DOKU_LF', "\n");
6if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t");
7if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
8
9require_once(DOKU_PLUGIN.'action.php');
10
11class action_plugin_podcast_feed extends DokuWiki_Action_Plugin{
12    var $entryhelper = null;
13    var $pcasthelper = null;
14    var $tools = null;
15    var $defaultConf = array(
16        'sortby' => 'created',
17        'sortorder' => 'DESC',
18    );
19    function action_plugin_podcast_feed() {
20        $this->entryhelper =& plugin_load('helper', 'blogtng_entry');
21        $this->pcasthelper =& plugin_load('helper', 'podcast');
22        $this->tools =& plugin_load('helper', 'blogtng_tools');
23    }
24    function register(&$controller) {
25        $controller->register_hook('FEED_OPTS_POSTPROCESS', 'AFTER', $this, 'handle_opts_postprocess', array());
26        $controller->register_hook('FEED_MODE_UNKNOWN', 'BEFORE', $this, 'handle_mode_unknown', array ());
27        $controller->register_hook('FEED_ITEM_ADD', 'BEFORE', $this, 'handle_item_add', array());
28    }
29    function handle_opts_postprocess(&$event, $param) {
30        $opt =& $event->data['opt'];
31        if ($opt['feed_mode'] != 'podcast') return;
32        $opt['blog'] = $_REQUEST['blog'];
33        $opt['tags'] = $_REQUEST['tags'];
34        $opt['sortby'] = $_REQUEST['sortby'];
35        $opt['sortorder'] = $_REQUEST['sortorder'];
36        $opt['podcast_format'] = $_REQUEST['podcast_format'];
37        $opt['podcast_extensions'] = explode( ',', $this->getConf( 'podcast_extensions' ));
38        $opt['feed_type'] = 'RSS2.0';
39    }
40    function handle_mode_unknown(&$event, $param) {
41        $opt = $event->data['opt'];
42        if ($opt['feed_mode'] !== 'podcast') return;
43        $event->preventDefault();
44        $event->data['data'] = array();
45        $conf = array(
46            'blog' => explode(',', $opt['blog']),
47            'tags' => ($opt['tags'] ? explode(',', $opt['tags']) : null),
48            'sortby' => $opt['sortby'],
49            'sortorder' => $opt['sortorder'],
50            'limit' => $opt['items'],
51            'offset' => 0,
52        );
53        $this->tools->cleanConf($conf);
54        $conf = array_merge($conf, $this->defaultConf);
55        $posts = $this->entryhelper->get_posts($conf);
56        if( $opt['feed_mode'] === 'podcast' ) {
57            // image -> url, title, link, widh, height, description
58            // language
59            // copyright
60            // category (array)
61            // rating
62        }
63        foreach ($posts as $row) {
64            if( auth_quickaclcheck( $row['id'] ) < AUTH_READ ) {
65                continue; }
66            if( $opt['feed_mode'] === 'podcast' ) {
67                $p = $this->pcasthelper->get_info( $row['page'] );
68                $row['data_entry'] = $p; }
69            $event->data['data'][] = array(
70                'id' => $row['page'],
71                'date' => $row['created'],
72                'user' => $row['mail']." (".$row['author'].")",
73                'entry' => $row );
74        }
75    }
76    function handle_item_add(&$event, $param) {
77        $opt = $event->data['opt'];
78        if ($opt['feed_mode'] !== 'podcast') return;
79        $opt['link_to'] = 'current';
80        $opt['item_content'] = 'html';
81
82        $length = 0;
83
84        $ditem = $event->data['ditem'];
85
86        // don't add drafts to the feed
87        if(p_get_metadata($ditem['id'], 'type') == 'draft') {
88            $event->preventDefault();
89            return;
90        }
91
92        // retrieve first heading from page instructions
93        $ins = p_cached_instructions(wikiFN($ditem['id']));
94        $headers = array_filter($ins, array($this, '_filterHeaders'));
95        $headingIns = array_shift($headers);
96        $firstheading = $headingIns[1][0];
97
98        $this->entryhelper->load_by_row($ditem['entry']);
99        $page_url = wl($id, 's=feed', true, '&');
100        $tag_url = wl( 'tags:', 's=feed', true, '&');
101
102        // get podcast data
103        $p = $event->data['ditem']['entry']['data_entry'];
104        $ext = ( $opt['podcast_format']
105          && in_array( $opt['podcast_format'], $opt['podcast_extensions'] ))
106              ? $opt['podcast_format']
107              : $this->getConf( 'podcast_filetype' );
108        if( isset( $p['files'][$ext] )) {
109          $file_url = $p['files'][$ext]['url'];
110          $length = $p['files'][$ext]['size'];
111          $filetype = 'audio/mpeg'; }
112
113        $output = '';
114        ob_start();
115        $this->entryhelper->tpl_content($ditem['entry']['blog'], 'feed');
116        $output = ob_get_contents();
117        ob_end_clean();
118        // make URLs work when canonical is not set, regexp instead of rerendering!
119        global $conf;
120        if(!$conf['canonical']){
121            $base = preg_quote(DOKU_REL,'/');
122            $output = preg_replace('/(<a href|<img src)="('.$base.')/s','$1="'.DOKU_URL,$output);
123        }
124        // strip first heading and replace item title
125
126
127        $event->data['item']->description = preg_replace('#[^\n]*?>\s*?' . preg_quote(hsc($firstheading), '#') . '\s*?<.*\n#', '', $output, 1);
128        $event->data['item']->title = $ditem['entry']['title'];
129        $event->data['item']->guid = getBaseURL( 1 ).$ditem['entry']['page'];
130
131        if( $length ) {
132          $event->data['item']->enclosure = (object)array(
133                  'url' => $file_url, 'length' => $length, 'type' => $filetype ); }
134
135#        if( $p['image'] ) { // kaputt
136#            $event->media = $p['image']; }
137
138        $output = '';
139        ob_start();
140        $this->entryhelper->tpl_tags( $tag_url );
141        $output = ob_get_contents();
142        ob_end_clean();
143    }
144
145    /**
146     * Returns true if $entry is a valid header instruction, false otherwise.
147     *
148     * @author Gina Häußge <osd@foosel.net>
149     */
150    function _filterHeaders($entry) {
151        // normal headers
152        if (is_array($entry) && $entry[0] == 'header' && count($entry) == 3 && is_array($entry[1]) && count($entry[1]) == 3)
153            return true;
154
155        // no known header
156        return false;
157    }
158}
159// vim:ts=4:sw=4:et:
160