<?php if (!defined('PmWiki')) exit();
/**
  PageListMultiTarget: enable a multiple links= argument in pagelists
  Written by (c) Petko Yotov 2013 www.pmwiki.org/petko
  Based on functions by (c) Patrick R. Michaud 2008 www.pmichaud.com

  This text is written for PmWiki; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published
  by the Free Software Foundation; either version 3 of the License, or
  (at your option) any later version. See pmwiki.php for full details
  and lack of warranty.
*/
# Version date
$RecipeInfo['PageListMultiTargets']['Version'] = '20151222';


SDVA($PageListFilters, array('PageListMultiTargets' => 150));

function PageListMultiTargets(&$list, &$opt, $pn, &$page) {
  global $EnablePLMTLink;
  static $reindex = array();
  if(IsEnabled($EnablePLMTLink, 0) && ! @$opt['links'] && @$opt['link']>'') {
    $opt['links'] = $opt['link'];
    unset($opt['link']);
  }

  if (! @$opt['links']) return 0;

  $fold = $GLOBALS['StrFoldFunction'];

  switch ($opt['=phase']) {
    case PAGELIST_PRE:
      if (@$opt['=cached']) return 0;
      $opt['=linksa'] = ParseArgs(str_replace(',', ' ', PLMTFixGlob($opt['links'])));
      if (isset($opt['=linksa']['']))
        $opt['=linksa'][''] = implode(',', $opt['=linksa']['']);
      if (isset($opt['=linksa']['-']))
        $opt['=linksa']['-'] = implode(',', $opt['=linksa']['-']);

      StopWatch("PageListMultiTargets begin count=".count($list));
      $xlist = PageIndexGrepLinks($opt['=linksa'], true);
      $list = array_diff($list, $xlist);
      StopWatch("PageListMultiTargets end count=".count($list));

      
      return PAGELIST_ITEM|PAGELIST_POST; 

    case PAGELIST_ITEM:
      if (!$page) { $page = ReadPage($pn, READPAGE_CURRENT); $opt['=readc']++; }
      if (!$page) return 0;
      $found = PageListMultiTargetsMatch($opt['=linksa'], explode(',', @$page['targets']));
      if ($found) return 1;
      $reindex[] = $pn;
      return 0;
      
    case PAGELIST_POST:
      if ($reindex) PageIndexQueueUpdate($reindex);
      $reindex = array();
      return 0;
  }
}

function PageListMultiTargetsMatch($links, $targets) {
  if(@$links['+']) foreach($links['+'] as $p) {
    if (count(MatchPageNames($targets, $p))==0 ) return 0;
  }
  if(@$links['']) {
    if(count(MatchPageNames($targets, $links['']))==0) return 0;
  }
  if(@$links['-']) {
    if(count(MatchPageNames($targets, $links['-']))>0) return 0;
  }
  return 1;
}

function PageIndexGrepLinks($links, $invert = false) {
  global $PageIndexFile;
  if (!$PageIndexFile) return array();
  StopWatch('PageIndexGrepLinks begin');
  $pagelist = array();
  $fp = @fopen($PageIndexFile, 'r');
  if ($fp) {
    while (!feof($fp)) {
      $line = fgets($fp, 4096);
      while (substr($line, -1, 1) != "\n" && !feof($fp))
        $line .= fgets($fp, 4096);
      $i = strpos($line, ':');
      if (!$i) continue;

      list($n, $t, $l) = explode(":", $line);
      $targets = explode(' ', trim($l));

      $add = PageListMultiTargetsMatch($links, $targets);
      if ($add xor $invert) $pagelist[] = $n;
    }
    fclose($fp);
  }
  StopWatch('PageIndexGrepLinks end');
  return $pagelist;
}
function PLMTFixGlob($x, $rep = '$1*.$2') {
  return preg_replace('/([\\s,][-!+]?)([^\\/.\\s,]+)(?=[\\s,])/', $rep, ",$x,");
}