10c3a5702SAndreas Gohr<?php 20c3a5702SAndreas Gohr 30c3a5702SAndreas Gohrnamespace dokuwiki\ChangeLog; 40c3a5702SAndreas Gohr 50c3a5702SAndreas Gohr/** 61d11f1d3SSatoshi Sahara * Class PageChangeLog; handles changelog of a wiki page 70c3a5702SAndreas Gohr */ 80c3a5702SAndreas Gohrclass PageChangeLog extends ChangeLog 90c3a5702SAndreas Gohr{ 100c3a5702SAndreas Gohr /** 110c3a5702SAndreas Gohr * Returns path to changelog 120c3a5702SAndreas Gohr * 130c3a5702SAndreas Gohr * @return string path to file 140c3a5702SAndreas Gohr */ 150c3a5702SAndreas Gohr protected function getChangelogFilename() 160c3a5702SAndreas Gohr { 170c3a5702SAndreas Gohr return metaFN($this->id, '.changes'); 180c3a5702SAndreas Gohr } 190c3a5702SAndreas Gohr 200c3a5702SAndreas Gohr /** 210c3a5702SAndreas Gohr * Returns path to current page/media 220c3a5702SAndreas Gohr * 23e49fa56bSSatoshi Sahara * @param string|int $rev empty string or revision timestamp 240c3a5702SAndreas Gohr * @return string path to file 250c3a5702SAndreas Gohr */ 26e49fa56bSSatoshi Sahara protected function getFilename($rev = '') 270c3a5702SAndreas Gohr { 28e49fa56bSSatoshi Sahara return wikiFN($this->id, $rev); 290c3a5702SAndreas Gohr } 30c7192766SSatoshi Sahara 31a835c93aSGerrit Uitslag /** 32a835c93aSGerrit Uitslag * Returns mode 33a835c93aSGerrit Uitslag * 34a835c93aSGerrit Uitslag * @return string RevisionInfo::MODE_PAGE 35a835c93aSGerrit Uitslag */ 36a835c93aSGerrit Uitslag protected function getMode() 37a835c93aSGerrit Uitslag { 38a835c93aSGerrit Uitslag return RevisionInfo::MODE_PAGE; 39a835c93aSGerrit Uitslag } 40c7192766SSatoshi Sahara 41c7192766SSatoshi Sahara /** 4201e8d739SAndreas Gohr * Returns path to the global page-changelog file 43c7192766SSatoshi Sahara * 4401e8d739SAndreas Gohr * @return string path to file 45c7192766SSatoshi Sahara */ 4601e8d739SAndreas Gohr protected function getGlobalChangelogFilename() 47c7192766SSatoshi Sahara { 48c7192766SSatoshi Sahara global $conf; 4901e8d739SAndreas Gohr return $conf['changelog']; 5001e8d739SAndreas Gohr } 51c7192766SSatoshi Sahara 5201e8d739SAndreas Gohr /** 5301e8d739SAndreas Gohr * Copy the externally-edited page to the attic at the synthesized revision date. 5401e8d739SAndreas Gohr * If the file mtime is older than the last known revision (broken chronology), 5501e8d739SAndreas Gohr * touch the file forward so future reads see a consistent state. 5601e8d739SAndreas Gohr * 5701e8d739SAndreas Gohr * @param array $revInfo synthesized revision info 5801e8d739SAndreas Gohr * @return bool true on success (or nothing to copy), false if the attic write failed 5901e8d739SAndreas Gohr */ 6001e8d739SAndreas Gohr protected function saveExternalAttic(array $revInfo) 6101e8d739SAndreas Gohr { 6201e8d739SAndreas Gohr $file = $this->getFilename(); 6301e8d739SAndreas Gohr if (!file_exists($file)) return true; 64c7192766SSatoshi Sahara 6501e8d739SAndreas Gohr // rescue: file mtime older than last revision — touch forward to the synthesized date 6601e8d739SAndreas Gohr if (empty($revInfo['timestamp'])) { 6701e8d739SAndreas Gohr if (!@touch($file, $revInfo['date'])) return false; 6801e8d739SAndreas Gohr clearstatcache(false, $file); 6901e8d739SAndreas Gohr } 70c7192766SSatoshi Sahara 7101e8d739SAndreas Gohr $atticfile = $this->getFilename($revInfo['date']); 7201e8d739SAndreas Gohr return io_writeWikiPage($atticfile, io_readWikiPage($file, $this->id, ''), $this->id, $revInfo['date']); 73c7192766SSatoshi Sahara } 74*0a245329SAndreas Gohr 75*0a245329SAndreas Gohr /** 76*0a245329SAndreas Gohr * Compare the current page content against the (gzip-aware) attic copy of a revision. 77*0a245329SAndreas Gohr * 78*0a245329SAndreas Gohr * Both sides are already loaded (and decompressed) into memory by io_readWikiPage, so 79*0a245329SAndreas Gohr * they are compared directly rather than via a hash: the string comparison stops at the 80*0a245329SAndreas Gohr * first differing byte and avoids hashing the full contents. 81*0a245329SAndreas Gohr * 82*0a245329SAndreas Gohr * @param int $rev revision timestamp to compare the current page against 83*0a245329SAndreas Gohr * @return bool true if the decompressed content is identical 84*0a245329SAndreas Gohr */ 85*0a245329SAndreas Gohr protected function currentContentMatchesRevision($rev) 86*0a245329SAndreas Gohr { 87*0a245329SAndreas Gohr $current = $this->getFilename(); 88*0a245329SAndreas Gohr $attic = $this->getFilename($rev); 89*0a245329SAndreas Gohr if (!file_exists($current) || !file_exists($attic)) return false; 90*0a245329SAndreas Gohr 91*0a245329SAndreas Gohr return io_readWikiPage($current, $this->id, '') === io_readWikiPage($attic, $this->id, $rev); 92*0a245329SAndreas Gohr } 930c3a5702SAndreas Gohr} 94