<?php
/*
 * Display Orphans Plugin
 * Copyright (c) 2016 Jay Jeckel
 * Licensed under the MIT license: https://opensource.org/licenses/MIT
 * Permission is granted to use, copy, modify, and distribute the work.
 * Full license information available in the project LICENSE file.
*/

if (!defined('DOKU_INC')) { die(); }

require_once(DOKU_INC . 'inc' . '/' . 'search.php');
require_once(dirname(__FILE__) . '/'. '_local.php');
use plugin\displayorphans\Util;
use plugin\displayorphans\Logic;

class helper_plugin_displayorphans extends DokuWiki_Plugin
{
    //const PATTERN_LINK = '/\[\[([^\]#\|\>\/\\\\@]+)(?:#[^\]\|]*)?(?:\|[^\]]*)?\]\]/';
    const PATTERN_LINK = '/\[\[([^\]#\?\|\>\/\\\\@]+)(?:#[^\]\|\?]*)?(?:\?[^\]\|]*)?(?:\|[^\]]*)?\]\]/';

    const IGNORE_BLOCKS = array('/<nowiki>.*?<\/nowiki>/su', '/%%.*?%%/su', '/<php>.*?<\/php>/su', '/<PHP>.*?<\/PHP>/su', '/<html>.*?<\/html>/su', '/<HTML>.*?<\/HTML>/su', '/^( {2,}|\t)[^\*\- ].*?$/mu', '/<code[^>]*?>.*?<\/code>/su', '/<file[^>]*?>.*?<\/file>/su');

    function /* array */ items(/* string */ $datadir, /* string */ $type)
    {
        $itemFilterPredicate = array('plugin\displayorphans\Logic', 'is' . ucfirst($type) . 'Page');
        if (!is_callable($itemFilterPredicate)) { return null; }

        $ignoredPages = Util::asList($this->getConf('ignore_' . $type . '_pages'), ' ');
        $ignoreNamespaces = Util::asList($this->getConf('ignore_' . $type . '_namespaces'), ' ');
        $items = $this->findItems($datadir, $itemFilterPredicate, $ignoredPages, $ignoreNamespaces);
        if (!empty($items)) { if ($this->getConf('sort_table_ascending')) { ksort($items); } else { krsort($items); } }
        return $items;
    }

    function /* array */ findItems(/* string */ $datadir, callable $filter = null, array $ignoredPages = null, array $ignoreNamespaces = null)
    {
        $all = $this->findAllItems($datadir);
        $items = array();
        foreach ($all as $id => $item)
        { if (empty($filter) || $filter($id, $item, $ignoredPages, $ignoreNamespaces)) { $items[$id] = $item; } }
        return $items;
    }

    function /* array */ findAllItems(/* string */ $datadir)
    {
        $items = array();
        search($items, $datadir, array($this, '_filterItem'), null);
        return $items;
    }

    function /* bool */ _filterItem(&$data, $base, /* string */ $file, /* string */ $type, $lvl, $opts)
    {
        if ($type == 'd') { return true; }
        else if (!preg_match("/.*\.txt$/", $file)) { return true; }

        $id = pathID($file);
        if (auth_quickaclcheck($id) < AUTH_READ) { return false; }

        if (array_key_exists($id, $data)) { $data[$id]['exists'] = true; }
        else { $data[$id] = array('exists' => true, 'count' => 0); }

        $links = $this->_findLinks($file);
        foreach ($links as $index => $link)
        {
            if (array_key_exists($link, $data)) { $data[$link]['count']++; }
            else { $data[$link] = array('exists' => false, 'count' => 1); }
        }
        return true;
    }

    function /* array */ _findLinks(/* string */ $file)
    {
        global $conf;

        $id = pathID($file);
        $text = @file_get_contents($conf['datadir'] . $file);
        foreach (self::IGNORE_BLOCKS as $index => $block) { $text = preg_replace($block, '',  $text); }
        $links = array();
        preg_match_all(self::PATTERN_LINK, $text, $links);
        $links = $links[1];
        foreach($links as $index => $link) { $links[$index] = $this->_resolveLink($id, $link); }
        return $links;
    }

    function /* string */ _resolveLink(/* string */ $source, /* string */ $target)
    { resolve_pageid(getNS($source), $target, $exists); return $target; }
}

//Setup VIM: ex: et ts=4 enc=utf-8 :
?>