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