17d559c7fSBen Coburn<?php 27d559c7fSBen Coburn/** 37d559c7fSBen Coburn * Changelog handling functions 47d559c7fSBen Coburn * 57d559c7fSBen Coburn * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 67d559c7fSBen Coburn * @author Andreas Gohr <andi@splitbrain.org> 77d559c7fSBen Coburn */ 87d559c7fSBen Coburn 97d559c7fSBen Coburn/** 107d559c7fSBen Coburn * parses a changelog line into it's components 117d559c7fSBen Coburn * 127d559c7fSBen Coburn * @author Ben Coburn <btcoburn@silicodon.net> 134f1e2cb3SGerrit Uitslag * 144f1e2cb3SGerrit Uitslag * @param string $line changelog line 154f1e2cb3SGerrit Uitslag * @return array|bool parsed line or false 167d559c7fSBen Coburn */ 177d559c7fSBen Coburnfunction parseChangelogLine($line) { 18ac3ed4afSGerrit Uitslag $line = rtrim($line, "\n"); 197d559c7fSBen Coburn $tmp = explode("\t", $line); 207d559c7fSBen Coburn if ($tmp !== false && count($tmp) > 1) { 217d559c7fSBen Coburn $info = array(); 22e16d739eSBen Coburn $info['date'] = (int)$tmp[0]; // unix timestamp 237d559c7fSBen Coburn $info['ip'] = $tmp[1]; // IPv4 address (127.0.0.1) 247d559c7fSBen Coburn $info['type'] = $tmp[2]; // log line type 257d559c7fSBen Coburn $info['id'] = $tmp[3]; // page id 267d559c7fSBen Coburn $info['user'] = $tmp[4]; // user name 277d559c7fSBen Coburn $info['sum'] = $tmp[5]; // edit summary (or action reason) 28ac3ed4afSGerrit Uitslag $info['extra'] = $tmp[6]; // extra data (varies by line type) 29ac3ed4afSGerrit Uitslag if (isset($tmp[7]) && $tmp[7] !== '') { //last item has line-end|| 30ac3ed4afSGerrit Uitslag $info['sizechange'] = (int) $tmp[7]; 31ac3ed4afSGerrit Uitslag } else { 32ac3ed4afSGerrit Uitslag $info['sizechange'] = null; 33ac3ed4afSGerrit Uitslag } 347d559c7fSBen Coburn return $info; 35ac3ed4afSGerrit Uitslag } else { 36ac3ed4afSGerrit Uitslag return false; 37ac3ed4afSGerrit Uitslag } 387d559c7fSBen Coburn} 397d559c7fSBen Coburn 407d559c7fSBen Coburn/** 4163f13cadSDamien Regad * Adds an entry to the changelog and saves the metadata for the page 427d559c7fSBen Coburn * 43*6527839fSSatoshi Sahara * Note: timestamp of the change might not be unique especially after very quick 44*6527839fSSatoshi Sahara * repeated edits (e.g. change checkbox via do plugin) 45*6527839fSSatoshi Sahara * 46*6527839fSSatoshi Sahara * @param int $date Timestamp of the change 47a365baeeSDominik Eckelmann * @param String $id Name of the affected page 48a365baeeSDominik Eckelmann * @param String $type Type of the change see DOKU_CHANGE_TYPE_* 49a365baeeSDominik Eckelmann * @param String $summary Summary of the change 50a365baeeSDominik Eckelmann * @param mixed $extra In case of a revert the revision (timestmp) of the reverted page 51a365baeeSDominik Eckelmann * @param array $flags Additional flags in a key value array. 524f1e2cb3SGerrit Uitslag * Available flags: 53a365baeeSDominik Eckelmann * - ExternalEdit - mark as an external edit. 54ac3ed4afSGerrit Uitslag * @param null|int $sizechange Change of filesize 55a365baeeSDominik Eckelmann * 567d559c7fSBen Coburn * @author Andreas Gohr <andi@splitbrain.org> 577d559c7fSBen Coburn * @author Esther Brunner <wikidesign@gmail.com> 587d559c7fSBen Coburn * @author Ben Coburn <btcoburn@silicodon.net> 597d559c7fSBen Coburn */ 605d9428a0SSatoshi Saharafunction addLogEntry( 615d9428a0SSatoshi Sahara $date, 625d9428a0SSatoshi Sahara $id, 635d9428a0SSatoshi Sahara $type = DOKU_CHANGE_TYPE_EDIT, 645d9428a0SSatoshi Sahara $summary = '', 655d9428a0SSatoshi Sahara $extra = '', 665d9428a0SSatoshi Sahara $flags = null, 675d9428a0SSatoshi Sahara $sizechange = null) 685d9428a0SSatoshi Sahara{ 697d559c7fSBen Coburn global $conf, $INFO; 70585bf44eSChristopher Smith /** @var Input $INPUT */ 71585bf44eSChristopher Smith global $INPUT; 727d559c7fSBen Coburn 735aa52fafSBen Coburn // check for special flags as keys 74252acce3SSatoshi Sahara if (!is_array($flags)) $flags = array(); 755aa52fafSBen Coburn $flagExternalEdit = isset($flags['ExternalEdit']); 765aa52fafSBen Coburn 777d559c7fSBen Coburn $id = cleanid($id); 787d559c7fSBen Coburn $file = wikiFN($id); 797d559c7fSBen Coburn $created = @filectime($file); 80ebf1501fSBen Coburn $minor = ($type === DOKU_CHANGE_TYPE_MINOR_EDIT); 81ebf1501fSBen Coburn $wasRemoved = ($type === DOKU_CHANGE_TYPE_DELETE); 827d559c7fSBen Coburn 837d559c7fSBen Coburn if (!$date) $date = time(); //use current time if none supplied 842f9daf16SAndreas Gohr $remote = (!$flagExternalEdit) ? clientIP(true) : '127.0.0.1'; 85585bf44eSChristopher Smith $user = (!$flagExternalEdit) ? $INPUT->server->str('REMOTE_USER') : ''; 86ac3ed4afSGerrit Uitslag if ($sizechange === null) { 87ac3ed4afSGerrit Uitslag $sizechange = ''; 88ac3ed4afSGerrit Uitslag } else { 89ac3ed4afSGerrit Uitslag $sizechange = (int) $sizechange; 90ac3ed4afSGerrit Uitslag } 917d559c7fSBen Coburn 927d559c7fSBen Coburn $strip = array("\t", "\n"); 937d559c7fSBen Coburn $logline = array( 947d559c7fSBen Coburn 'date' => $date, 957d559c7fSBen Coburn 'ip' => $remote, 967d559c7fSBen Coburn 'type' => str_replace($strip, '', $type), 977d559c7fSBen Coburn 'id' => $id, 987d559c7fSBen Coburn 'user' => $user, 998cbc5ee8SAndreas Gohr 'sum' => \dokuwiki\Utf8\PhpString::substr(str_replace($strip, '', $summary), 0, 255), 100ac3ed4afSGerrit Uitslag 'extra' => str_replace($strip, '', $extra), 101ac3ed4afSGerrit Uitslag 'sizechange' => $sizechange 1027d559c7fSBen Coburn ); 1037d559c7fSBen Coburn 104fed2ee90SGerrit Uitslag $wasCreated = ($type === DOKU_CHANGE_TYPE_CREATE); 105fed2ee90SGerrit Uitslag $wasReverted = ($type === DOKU_CHANGE_TYPE_REVERT); 1067d559c7fSBen Coburn // update metadata 1077d559c7fSBen Coburn if (!$wasRemoved) { 10863f13cadSDamien Regad $oldmeta = p_read_metadata($id)['persistent']; 1097d559c7fSBen Coburn $meta = array(); 110bba3d825SAndreas Gohr if ( 111bba3d825SAndreas Gohr $wasCreated && ( 11263f13cadSDamien Regad empty($oldmeta['date']['created']) || 11363f13cadSDamien Regad $oldmeta['date']['created'] === $created 114bba3d825SAndreas Gohr ) 115bba3d825SAndreas Gohr ) { 11664159a61SAndreas Gohr // newly created 1177d559c7fSBen Coburn $meta['date']['created'] = $created; 118a8e72133SAndreas Gohr if ($user) { 119aac83cd4SPhy $meta['creator'] = isset($INFO) ? $INFO['userinfo']['name'] : null; 120a8e72133SAndreas Gohr $meta['user'] = $user; 121a8e72133SAndreas Gohr } 12263f13cadSDamien Regad } elseif (($wasCreated || $wasReverted) && !empty($oldmeta['date']['created'])) { 12364159a61SAndreas Gohr // re-created / restored 12463f13cadSDamien Regad $meta['date']['created'] = $oldmeta['date']['created']; 1253d1f9ec3SMichael Klier $meta['date']['modified'] = $created; // use the files ctime here 12663f13cadSDamien Regad $meta['creator'] = isset($oldmeta['creator']) ? $oldmeta['creator'] : null; 127aac83cd4SPhy if ($user) $meta['contributor'][$user] = isset($INFO) ? $INFO['userinfo']['name'] : null; 1287d559c7fSBen Coburn } elseif (!$minor) { // non-minor modification 1297d559c7fSBen Coburn $meta['date']['modified'] = $date; 130aac83cd4SPhy if ($user) $meta['contributor'][$user] = isset($INFO) ? $INFO['userinfo']['name'] : null; 1317d559c7fSBen Coburn } 1327d559c7fSBen Coburn $meta['last_change'] = $logline; 133ee4d22e0SChristopher Smith p_set_metadata($id, $meta); 1347d559c7fSBen Coburn } 1357d559c7fSBen Coburn 1367d559c7fSBen Coburn // add changelog lines 1377d559c7fSBen Coburn $logline = implode("\t", $logline)."\n"; 1387d559c7fSBen Coburn io_saveFile(metaFN($id,'.changes'), $logline, true); //page changelog 1397d559c7fSBen Coburn io_saveFile($conf['changelog'], $logline, true); //global changelog cache 1407d559c7fSBen Coburn} 1417d559c7fSBen Coburn 1427d559c7fSBen Coburn/** 14399c8d7f2Smichael * Add's an entry to the media changelog 14499c8d7f2Smichael * 14599c8d7f2Smichael * @author Michael Hamann <michael@content-space.de> 14699c8d7f2Smichael * @author Andreas Gohr <andi@splitbrain.org> 14799c8d7f2Smichael * @author Esther Brunner <wikidesign@gmail.com> 14899c8d7f2Smichael * @author Ben Coburn <btcoburn@silicodon.net> 1494f1e2cb3SGerrit Uitslag * 1504f1e2cb3SGerrit Uitslag * @param int $date Timestamp of the change 1514f1e2cb3SGerrit Uitslag * @param String $id Name of the affected page 1524f1e2cb3SGerrit Uitslag * @param String $type Type of the change see DOKU_CHANGE_TYPE_* 1534f1e2cb3SGerrit Uitslag * @param String $summary Summary of the change 1544f1e2cb3SGerrit Uitslag * @param mixed $extra In case of a revert the revision (timestmp) of the reverted page 1554f1e2cb3SGerrit Uitslag * @param array $flags Additional flags in a key value array. 1564f1e2cb3SGerrit Uitslag * Available flags: 1574f1e2cb3SGerrit Uitslag * - (none, so far) 158ac3ed4afSGerrit Uitslag * @param null|int $sizechange Change of filesize 15999c8d7f2Smichael */ 16064159a61SAndreas Gohrfunction addMediaLogEntry( 16164159a61SAndreas Gohr $date, 16264159a61SAndreas Gohr $id, 16364159a61SAndreas Gohr $type = DOKU_CHANGE_TYPE_EDIT, 16464159a61SAndreas Gohr $summary = '', 16564159a61SAndreas Gohr $extra = '', 16664159a61SAndreas Gohr $flags = null, 16764159a61SAndreas Gohr $sizechange = null) 16864159a61SAndreas Gohr{ 169de3eb1d7SAdrian Lang global $conf; 170585bf44eSChristopher Smith /** @var Input $INPUT */ 171585bf44eSChristopher Smith global $INPUT; 17299c8d7f2Smichael 173facfe250SSatoshi Sahara // check for special flags as keys 174facfe250SSatoshi Sahara if (!is_array($flags)) $flags = array(); 175facfe250SSatoshi Sahara $flagExternalEdit = isset($flags['ExternalEdit']); 176facfe250SSatoshi Sahara 17799c8d7f2Smichael $id = cleanid($id); 17899c8d7f2Smichael 17999c8d7f2Smichael if (!$date) $date = time(); //use current time if none supplied 180facfe250SSatoshi Sahara $remote = (!$flagExternalEdit) ? clientIP(true) : '127.0.0.1'; 181facfe250SSatoshi Sahara $user = (!$flagExternalEdit) ? $INPUT->server->str('REMOTE_USER') : ''; 182ac3ed4afSGerrit Uitslag if ($sizechange === null) { 183ac3ed4afSGerrit Uitslag $sizechange = ''; 184ac3ed4afSGerrit Uitslag } else { 185ac3ed4afSGerrit Uitslag $sizechange = (int) $sizechange; 186ac3ed4afSGerrit Uitslag } 18799c8d7f2Smichael 18899c8d7f2Smichael $strip = array("\t", "\n"); 18999c8d7f2Smichael $logline = array( 19099c8d7f2Smichael 'date' => $date, 19199c8d7f2Smichael 'ip' => $remote, 19299c8d7f2Smichael 'type' => str_replace($strip, '', $type), 19399c8d7f2Smichael 'id' => $id, 19499c8d7f2Smichael 'user' => $user, 1958cbc5ee8SAndreas Gohr 'sum' => \dokuwiki\Utf8\PhpString::substr(str_replace($strip, '', $summary), 0, 255), 196ac3ed4afSGerrit Uitslag 'extra' => str_replace($strip, '', $extra), 197ac3ed4afSGerrit Uitslag 'sizechange' => $sizechange 19899c8d7f2Smichael ); 19999c8d7f2Smichael 20099c8d7f2Smichael // add changelog lines 20199c8d7f2Smichael $logline = implode("\t", $logline)."\n"; 20299c8d7f2Smichael io_saveFile($conf['media_changelog'], $logline, true); //global media changelog cache 203e4f389efSKate Arzamastseva io_saveFile(mediaMetaFN($id,'.changes'), $logline, true); //media file's changelog 20499c8d7f2Smichael} 20599c8d7f2Smichael 20699c8d7f2Smichael/** 207252acce3SSatoshi Sahara * returns an array of recently changed files using the changelog 2087d559c7fSBen Coburn * 2097d559c7fSBen Coburn * The following constants can be used to control which changes are 2107d559c7fSBen Coburn * included. Add them together as needed. 2117d559c7fSBen Coburn * 2127d559c7fSBen Coburn * RECENTS_SKIP_DELETED - don't include deleted pages 2137d559c7fSBen Coburn * RECENTS_SKIP_MINORS - don't include minor changes 21408e9b52fSPhy * RECENTS_ONLY_CREATION - only include new created pages and media 2157d559c7fSBen Coburn * RECENTS_SKIP_SUBSPACES - don't include subspaces 2160b926329SKate Arzamastseva * RECENTS_MEDIA_CHANGES - return media changes instead of page changes 2170b926329SKate Arzamastseva * RECENTS_MEDIA_PAGES_MIXED - return both media changes and page changes 2187d559c7fSBen Coburn * 2197d559c7fSBen Coburn * @param int $first number of first entry returned (for paginating 2207d559c7fSBen Coburn * @param int $num return $num entries 2217d559c7fSBen Coburn * @param string $ns restrict to given namespace 22259f20ea3SMichael Hamann * @param int $flags see above 22359f20ea3SMichael Hamann * @return array recently changed files 2247d559c7fSBen Coburn * 2257d559c7fSBen Coburn * @author Ben Coburn <btcoburn@silicodon.net> 22629778747SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 2277d559c7fSBen Coburn */ 2287d559c7fSBen Coburnfunction getRecents($first, $num, $ns = '', $flags = 0) { 2297d559c7fSBen Coburn global $conf; 2307d559c7fSBen Coburn $recent = array(); 2317d559c7fSBen Coburn $count = 0; 2327d559c7fSBen Coburn 2337d559c7fSBen Coburn if (!$num) 2347d559c7fSBen Coburn return $recent; 2357d559c7fSBen Coburn 2367d559c7fSBen Coburn // read all recent changes. (kept short) 2370b926329SKate Arzamastseva if ($flags & RECENTS_MEDIA_CHANGES) { 2388e3e8693SAndreas Gohr $lines = @file($conf['media_changelog']) ?: []; 23999c8d7f2Smichael } else { 2408e3e8693SAndreas Gohr $lines = @file($conf['changelog']) ?: []; 24199c8d7f2Smichael } 2421b266025SPhy if (!is_array($lines)) { 2431b266025SPhy $lines = array(); 2441b266025SPhy } 24529778747SKate Arzamastseva $lines_position = count($lines) - 1; 24659f20ea3SMichael Hamann $media_lines_position = 0; 24759f20ea3SMichael Hamann $media_lines = array(); 24829778747SKate Arzamastseva 2490b926329SKate Arzamastseva if ($flags & RECENTS_MEDIA_PAGES_MIXED) { 2508e3e8693SAndreas Gohr $media_lines = @file($conf['media_changelog']) ?: []; 2511b266025SPhy if (!is_array($media_lines)) { 2521b266025SPhy $media_lines = array(); 2531b266025SPhy } 25429778747SKate Arzamastseva $media_lines_position = count($media_lines) - 1; 25529778747SKate Arzamastseva } 25629778747SKate Arzamastseva 25729778747SKate Arzamastseva $seen = array(); // caches seen lines, _handleRecent() skips them 2587d559c7fSBen Coburn 2597d559c7fSBen Coburn // handle lines 2600b926329SKate Arzamastseva while ($lines_position >= 0 || (($flags & RECENTS_MEDIA_PAGES_MIXED) && $media_lines_position >= 0)) { 26129778747SKate Arzamastseva if (empty($rec) && $lines_position >= 0) { 2621d901ab2SAndreas Gohr $rec = _handleRecent(@$lines[$lines_position], $ns, $flags, $seen); 26329778747SKate Arzamastseva if (!$rec) { 26429778747SKate Arzamastseva $lines_position --; 26529778747SKate Arzamastseva continue; 26629778747SKate Arzamastseva } 26729778747SKate Arzamastseva } 2680b926329SKate Arzamastseva if (($flags & RECENTS_MEDIA_PAGES_MIXED) && empty($media_rec) && $media_lines_position >= 0) { 26964159a61SAndreas Gohr $media_rec = _handleRecent( 27064159a61SAndreas Gohr @$media_lines[$media_lines_position], 27164159a61SAndreas Gohr $ns, 27264159a61SAndreas Gohr $flags | RECENTS_MEDIA_CHANGES, 27364159a61SAndreas Gohr $seen 27464159a61SAndreas Gohr ); 27529778747SKate Arzamastseva if (!$media_rec) { 27629778747SKate Arzamastseva $media_lines_position --; 27729778747SKate Arzamastseva continue; 27829778747SKate Arzamastseva } 27929778747SKate Arzamastseva } 2800b926329SKate Arzamastseva if (($flags & RECENTS_MEDIA_PAGES_MIXED) && @$media_rec['date'] >= @$rec['date']) { 28129778747SKate Arzamastseva $media_lines_position--; 28229778747SKate Arzamastseva $x = $media_rec; 283b5941dfaSKate Arzamastseva $x['media'] = true; 28429778747SKate Arzamastseva $media_rec = false; 28529778747SKate Arzamastseva } else { 28629778747SKate Arzamastseva $lines_position--; 28729778747SKate Arzamastseva $x = $rec; 288421ec38eSKate Arzamastseva if ($flags & RECENTS_MEDIA_CHANGES) $x['media'] = true; 28929778747SKate Arzamastseva $rec = false; 29029778747SKate Arzamastseva } 2917d559c7fSBen Coburn if (--$first >= 0) continue; // skip first entries 29229778747SKate Arzamastseva $recent[] = $x; 2937d559c7fSBen Coburn $count++; 2947d559c7fSBen Coburn // break when we have enough entries 2957d559c7fSBen Coburn if ($count >= $num) { break; } 2967d559c7fSBen Coburn } 2977d559c7fSBen Coburn return $recent; 2987d559c7fSBen Coburn} 2997d559c7fSBen Coburn 3007d559c7fSBen Coburn/** 30199c8d7f2Smichael * returns an array of files changed since a given time using the 30299c8d7f2Smichael * changelog 30399c8d7f2Smichael * 30499c8d7f2Smichael * The following constants can be used to control which changes are 30599c8d7f2Smichael * included. Add them together as needed. 30699c8d7f2Smichael * 30799c8d7f2Smichael * RECENTS_SKIP_DELETED - don't include deleted pages 30899c8d7f2Smichael * RECENTS_SKIP_MINORS - don't include minor changes 30908e9b52fSPhy * RECENTS_ONLY_CREATION - only include new created pages and media 31099c8d7f2Smichael * RECENTS_SKIP_SUBSPACES - don't include subspaces 3110b926329SKate Arzamastseva * RECENTS_MEDIA_CHANGES - return media changes instead of page changes 31299c8d7f2Smichael * 31399c8d7f2Smichael * @param int $from date of the oldest entry to return 31499c8d7f2Smichael * @param int $to date of the newest entry to return (for pagination, optional) 31599c8d7f2Smichael * @param string $ns restrict to given namespace (optional) 31659f20ea3SMichael Hamann * @param int $flags see above (optional) 31759f20ea3SMichael Hamann * @return array of files 31899c8d7f2Smichael * 31999c8d7f2Smichael * @author Michael Hamann <michael@content-space.de> 32099c8d7f2Smichael * @author Ben Coburn <btcoburn@silicodon.net> 32199c8d7f2Smichael */ 32299c8d7f2Smichaelfunction getRecentsSince($from, $to = null, $ns = '', $flags = 0) { 32399c8d7f2Smichael global $conf; 32499c8d7f2Smichael $recent = array(); 32599c8d7f2Smichael 32699c8d7f2Smichael if ($to && $to < $from) 32799c8d7f2Smichael return $recent; 32899c8d7f2Smichael 32999c8d7f2Smichael // read all recent changes. (kept short) 3300b926329SKate Arzamastseva if ($flags & RECENTS_MEDIA_CHANGES) { 33199c8d7f2Smichael $lines = @file($conf['media_changelog']); 33299c8d7f2Smichael } else { 33399c8d7f2Smichael $lines = @file($conf['changelog']); 33499c8d7f2Smichael } 335e920a0a1SAndreas Gohr if (!$lines) return $recent; 33699c8d7f2Smichael 33799c8d7f2Smichael // we start searching at the end of the list 33899c8d7f2Smichael $lines = array_reverse($lines); 33999c8d7f2Smichael 34099c8d7f2Smichael // handle lines 34199c8d7f2Smichael $seen = array(); // caches seen lines, _handleRecent() skips them 34299c8d7f2Smichael 34399c8d7f2Smichael foreach ($lines as $line) { 34499c8d7f2Smichael $rec = _handleRecent($line, $ns, $flags, $seen); 34599c8d7f2Smichael if ($rec !== false) { 34699c8d7f2Smichael if ($rec['date'] >= $from) { 34799c8d7f2Smichael if (!$to || $rec['date'] <= $to) { 34899c8d7f2Smichael $recent[] = $rec; 34999c8d7f2Smichael } 35099c8d7f2Smichael } else { 35199c8d7f2Smichael break; 35299c8d7f2Smichael } 35399c8d7f2Smichael } 35499c8d7f2Smichael } 35599c8d7f2Smichael 35699c8d7f2Smichael return array_reverse($recent); 35799c8d7f2Smichael} 35899c8d7f2Smichael 35999c8d7f2Smichael/** 3607d559c7fSBen Coburn * Internal function used by getRecents 3617d559c7fSBen Coburn * 3627d559c7fSBen Coburn * don't call directly 3637d559c7fSBen Coburn * 3647d559c7fSBen Coburn * @see getRecents() 3657d559c7fSBen Coburn * @author Andreas Gohr <andi@splitbrain.org> 3667d559c7fSBen Coburn * @author Ben Coburn <btcoburn@silicodon.net> 3674f1e2cb3SGerrit Uitslag * 3684f1e2cb3SGerrit Uitslag * @param string $line changelog line 3694f1e2cb3SGerrit Uitslag * @param string $ns restrict to given namespace 3704f1e2cb3SGerrit Uitslag * @param int $flags flags to control which changes are included 3714f1e2cb3SGerrit Uitslag * @param array $seen listing of seen pages 3724f1e2cb3SGerrit Uitslag * @return array|bool false or array with info about a change 3737d559c7fSBen Coburn */ 37499c8d7f2Smichaelfunction _handleRecent($line, $ns, $flags, &$seen) { 3757d559c7fSBen Coburn if (empty($line)) return false; //skip empty lines 3767d559c7fSBen Coburn 3777d559c7fSBen Coburn // split the line into parts 3787d559c7fSBen Coburn $recent = parseChangelogLine($line); 379252acce3SSatoshi Sahara if ($recent === false) return false; 3807d559c7fSBen Coburn 3817d559c7fSBen Coburn // skip seen ones 3827d559c7fSBen Coburn if (isset($seen[$recent['id']])) return false; 3837d559c7fSBen Coburn 38408e9b52fSPhy // skip changes, of only new items are requested 38508e9b52fSPhy if ($recent['type'] !== DOKU_CHANGE_TYPE_CREATE && ($flags & RECENTS_ONLY_CREATION)) return false; 38668f43bcfSTero Kivinen 3877d559c7fSBen Coburn // skip minors 388ebf1501fSBen Coburn if ($recent['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT && ($flags & RECENTS_SKIP_MINORS)) return false; 3897d559c7fSBen Coburn 3907d559c7fSBen Coburn // remember in seen to skip additional sights 3917d559c7fSBen Coburn $seen[$recent['id']] = 1; 3927d559c7fSBen Coburn 3937d559c7fSBen Coburn // check if it's a hidden page 3947d559c7fSBen Coburn if (isHiddenPage($recent['id'])) return false; 3957d559c7fSBen Coburn 3967d559c7fSBen Coburn // filter namespace 3977d559c7fSBen Coburn if (($ns) && (strpos($recent['id'], $ns.':') !== 0)) return false; 3987d559c7fSBen Coburn 3997d559c7fSBen Coburn // exclude subnamespaces 4007d559c7fSBen Coburn if (($flags & RECENTS_SKIP_SUBSPACES) && (getNS($recent['id']) != $ns)) return false; 4017d559c7fSBen Coburn 4027d559c7fSBen Coburn // check ACL 40342025dfdSMichael Hamann if ($flags & RECENTS_MEDIA_CHANGES) { 40442025dfdSMichael Hamann $recent['perms'] = auth_quickaclcheck(getNS($recent['id']).':*'); 40542025dfdSMichael Hamann } else { 40699c8d7f2Smichael $recent['perms'] = auth_quickaclcheck($recent['id']); 40742025dfdSMichael Hamann } 40899c8d7f2Smichael if ($recent['perms'] < AUTH_READ) return false; 4097d559c7fSBen Coburn 4107d559c7fSBen Coburn // check existance 4111d901ab2SAndreas Gohr if ($flags & RECENTS_SKIP_DELETED) { 41242025dfdSMichael Hamann $fn = (($flags & RECENTS_MEDIA_CHANGES) ? mediaFN($recent['id']) : wikiFN($recent['id'])); 41379e79377SAndreas Gohr if (!file_exists($fn)) return false; 4141d901ab2SAndreas Gohr } 4157d559c7fSBen Coburn 4167d559c7fSBen Coburn return $recent; 4177d559c7fSBen Coburn} 4185d9428a0SSatoshi Sahara