<?php
/**
 * Downloads Plugin: agglomerate several download wiki pages into another
 * Usage:
 * {{downloads>namespace}} add all dist_YYYYMMDD wiki pages from namespace
 * {{downloads>namespace#count}} add at most count wiki pages
 *
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Gwenole Beauchesne <masked-email>
 */
 
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
 
 
/**
 * All DokuWiki plugins to extend the parser/rendering mechanism
 * need to inherit from this class
 */
class syntax_plugin_downloads extends DokuWiki_Syntax_Plugin {
 
    /**
     * return some info
     */
    function getInfo(){
        return array(
            'author' => 'Gwenole Beauchesne',
            'email'  => '<masked-email>',
            'date'   => '2005-11-06',
            'name'   => 'Downloads Plugin',
            'desc'   => 'Agglomerate several download wiki pages within another',
            'url'    => '',
        );
    }
 
    /**
     * What kind of syntax are we?
     */
    function getType(){
        return 'substition';
    }
 
    /**
     * Where to sort in?
     */
    function getSort(){
        return 311;
    }
 
    /**
     * Paragraph Type
     */
    function getPType(){
        return 'block';
    }
 
    /**
     * Connect pattern to lexer
     */
    function connectTo($mode) {
      $this->Lexer->addSpecialPattern("{{downloads>.+?}}",$mode,'plugin_downloads');
    }
 
    /**
     * Handle the match
     */
    function handle($match, $state, $pos, &$handler){
        global $ID;
        global $filechain;
 
		$maxd = 100;                                  // more than 100 downloads pages is getting insane
        $match = substr($match,12,-2);                // strip markup
        list($ns,$num) = explode('#',$match,2);       // split hash from namespace
        if (!is_numeric($num)) $num = $maxd;          // default to "all" download items
 
        function _isDistID($id) {
          list($tag,$date) = explode('_',noNS($id),2);
          return $tag === 'dist' && is_numeric($date);
        }
 
        $dpages = array_map(create_function('$var','return $var["id"];'),getRecents(0,$maxd,false,$ns,false));
        $dpages = array_filter($dpages, '_isDistID');
		if (!rsort($dpages)) return false;
		$chunks = array_chunk($dpages,$num);
		$dpages = $chunks[0];
 
        // check for and establish start of $filechain
        if (!isset($filechain)) $filechain[] = $ID;
 
        // don't allow the same file to be included more than once
        if (in_array($match[0], $filechain)) return false;
 
        // add included pages to the filechain
        $filechain = array_merge($filechain, $dpages);
 
        return $dpages;
    }    
 
    /**
     * Create output
     */
    function render($mode, &$renderer, $data) {
 
        if($mode == 'xhtml'){
          for ($i = 0; $i < sizeof($data); $i++){
            $id = $data[$i];
            $file = wikiFN($id);
            if (!@file_exists($file)) return false;
 
            // get instructions
            $instr = p_cached_instructions($file, false);
 
            // correct relative internal links and media
            $instr = $this->_correctRelNS($instr, $id);
 
            // render the instructructions on the fly
            $text = p_render('xhtml',$instr,$info);
 
            // remove toc, section edit buttons and category tags
            $patterns = array('!<div class="toc">.*?(</div>\n</div>)!s',
                              '#<!-- SECTION \[(\d*-\d*)\] -->#e',
                              '!<div class="category">.*?</div>!s');
            $replace  = array('','','');
            $text = preg_replace($patterns,$replace,$text);
 
            // prevent caching to ensure the included page is always fresh
            $renderer->info['cache'] = FALSE;
 
            // embed the included page
            if ($i)
              $renderer->doc .= '<hr noshade="noshade" size="1" />';
            $renderer->doc .= $text;
          }
          return true;
        }
        return false;
    }
 
    /**
     * Corrects relative internal links and media
     */
    function _correctRelNS($instr,$incl){
        global $ID;
 
        // check if included page is in same namespace
        $iNS = getNS($incl);
        if (getNS($ID) == $iNS) return $instr;
 
        // convert internal links and media from relative to absolute
        $n = count($instr);
        for($i = 0; $i < $n; $i++){
            if (substr($instr[$i][0], 0, 8) == 'internal'){
 
                // relative subnamespace
                if ($instr[$i][1][0]{0} == '.'){
 
                    $instr[$i][1][0] = $iNS.':'.substr($instr[$i][1][0], 1);
 
                // relative link
                } elseif (strpos($instr[$i][1][0],':') === false) {
                    $instr[$i][1][0] = $iNS.':'.$instr[$i][1][0];
                }
            }
        }
        return $instr;
    }
}
 
//Setup VIM: ex: et ts=4 enc=utf-8 :