1<?php 2/** 3 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 4 * @author Esther Brunner <wikidesign@gmail.com> 5 */ 6 7/* ----- Settings ----- */ 8 9define('DOKU_INC', realpath(dirname(__FILE__) . '/../../../') . '/'); 10const DISCUSSION_NS = 'discussion'; 11 12/* ----- Main ----- */ 13 14// conversion script should only be run once 15if (@file_exists(dirname(__FILE__) . '/convert_completed')) { 16 die('Conversion already completed.'); 17} 18 19require_once(DOKU_INC . 'inc/init.php'); 20 21$files = getDiscussionPages(); 22$n = 0; 23 24foreach ($files as $file) { 25 if (convertDiscussionPage($file)) { 26 echo $file['id'] . '<br />'; 27 $n++; 28 } 29} 30 31if ($n > 0) { 32 io_saveFile(dirname(__FILE__) . '/convert_completed', ''); 33 echo '<br />Successfully converted ' . $n . ' discussion pages to new comments meta files.'; 34} else { 35 echo 'No discussion pages found.'; 36} 37 38/* ----- Functions ----- */ 39 40/** 41 * returns a list of all discussion pages in the wiki 42 */ 43function getDiscussionPages() 44{ 45 global $conf; 46 47 $data = []; 48 search($data, $conf['datadir'], 'search_discussionpages', []); 49 return $data; 50} 51 52/** 53 * function for the search callback 54 */ 55function search_discussionpages(&$data, $base, $file, $type, $lvl, $opts) 56{ 57 global $conf; 58 59 // recurse into directories 60 if ($type == 'd') { 61 return true; 62 } 63 if (!preg_match('#' . preg_quote('/' . DISCUSSION_NS . '/', '#') . '#u', $file)) { 64 return false; 65 } 66 if (!preg_match('#\.txt$#', $file)) { 67 return false; 68 } 69 70 $id = pathID(str_replace(DISCUSSION_NS . '/', '', $file)); 71 $data[] = [ 72 'id' => $id, 73 'old' => $conf['datadir'] . $file, 74 'new' => metaFN($id, '.comments') 75 ]; 76 return true; 77} 78 79/** 80 * this converts individual discussion pages to .comment meta files 81 */ 82function convertDiscussionPage($file) 83{ 84 85 // read the old file 86 $data = io_readFile($file['old'], false); 87 88 // handle file with no comments yet 89 if (trim($data) == '') { 90 io_saveFile($file['new'], serialize(['status' => 1, 'number' => 0])); 91 @unlink($file['old']); 92 return true; 93 } 94 95 // break it up into pieces 96 $old = explode('----', $data); 97 98 // merge with possibly already existing (newer) comments 99 $comments = []; 100 if (@file_exists($file['new'])) { 101 $comments = unserialize(io_readFile($file['old'], false)); 102 } 103 104 // set general info 105 if (!isset($comments['status'])) { 106 $comments['status'] = 1; 107 } 108 $comments['number'] += count($old); 109 110 foreach ($old as $comment) { 111 112 // prepare comment data 113 if (strpos($comment, '<sub>') !== false) { 114 $in = '<sub>'; 115 $out = ':</sub>'; 116 } else { 117 $in = '//'; 118 $out = ': //'; 119 } 120 list($meta, $raw) = array_pad(explode($out, $comment, 2), 2, ''); 121 $raw = trim($raw); 122 123 // skip empty comments 124 if (!$raw) { 125 $comments['number']--; 126 continue; 127 } 128 129 list($mail, $meta) = array_pad(explode($in, $meta, 2), 2, ''); 130 list($name, $strd) = array_pad(explode(', ', $meta, 2), 2, ''); 131 $date = strtotime($strd); 132 if ($date == -1) { 133 $date = time(); 134 } 135 if ($mail) { 136 list($mail) = array_pad(explode(' |', $mail, 2), 2, ''); 137 $mail = substr(strrchr($mail, '>'), 1); 138 } 139 $cid = md5($name . $date); 140 141 // render comment 142 $xhtml = p_render('xhtml', p_get_instructions($raw), $info); 143 144 // fill in the converted comment 145 $comments['comments'][$cid] = [ 146 'user' => [ 147 'name' => hsc($name), 148 'mail' => hsc($mail)], 149 'date' => ['created' => $date], 150 'show' => true, 151 'raw' => $raw, 152 'xhtml' => $xhtml, 153 'replies' => [] 154 ]; 155 } 156 157 // save the new file 158 io_saveFile($file['new'], serialize($comments)); 159 160 // remove the old file 161 @unlink($file['old']); 162 163 return true; 164} 165