1<?php 2/** 3 * DokuWiki Plugin survey (Helper Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author DRINGOT <ddonovan.ringot@hotmail.fr> 7 */ 8 9// must be run within Dokuwiki 10if (!defined("DOKU_INC")) { 11 die(); 12} 13 14if (!defined("DOKU_LF")) { 15 define("DOKU_LF", "\n"); 16} 17if (!defined("DOKU_TAB")) { 18 define("DOKU_TAB", "\t"); 19} 20if (!defined("DOKU_PLUGIN")) { 21 define("DOKU_PLUGIN", DOKU_INC . "lib/plugins/"); 22} 23 24class helper_plugin_survey_survey extends DokuWiki_Plugin 25{ 26 public function getMethods() 27 { 28 return [ 29 [ 30 "name" => "sanitizeSyntax", 31 "desc" => "Clean syntax before interpreting it", 32 "params" => [ 33 "The syntax to sanitize" => "string", 34 ], 35 "return" => [ 36 "Sanitized Syntaxstring" => "string", 37 ], 38 ], 39 [ 40 "name" => "interpretSurvey", 41 "desc" => 42 "Interprets survey syntax text and returns " . 43 "a survey configuration", 44 "params" => [ 45 "Syntax text for the survey" => "string", 46 "Current line in the syntax" => "int", 47 "Current level of survey" => "int", 48 ], 49 "return" => [ 50 "The survey configuration as a hash" => "array", 51 ], 52 ], 53 ]; 54 } 55 56 /** 57 * Clean syntax before interpreting it 58 * 59 * @param String $surveySyntax The syntax to sanitize 60 * 61 * @return String Sanitized Syntaxstring 62 */ 63 64 public function sanitizeSyntax($surveySyntax) 65 { 66 // Remove \r's from the syntax. 67 68 $surveySyntax = preg_replace("/\r/", "", $surveySyntax); 69 70 // Sanitize syntax. Remove empty lines and such 71 72 $tmp = []; 73 74 $surveyArray = explode("\n", $surveySyntax); 75 76 foreach ($surveyArray as $syntaxLine) { 77 // Only use good syntax, discard other lines 78 79 if (preg_match('/^ * \* .*$/', $syntaxLine)) { 80 $tmp[] = $syntaxLine; 81 } else { 82 dbglog( 83 "Discarded survey syntaxline: " . $syntaxLine, 84 "Survey-Plugin SanitizeSyntax" 85 ); 86 } 87 } 88 89 return implode("\n", $tmp); 90 } 91 92 public function renderText($lineText) 93 { 94 // Link 95 96 if (preg_match("/\[\[(.*)\]\]/", $lineText, $matches)) { 97 if (preg_match("/^([^|]*)\|(.*)$/", $matches[1], $titleMatches)) { 98 $link = $titleMatches[1]; 99 $name = $titleMatches[2]; 100 } else { 101 $link = $name = $matches[1]; 102 } 103 104 if (preg_match("/^(http|ftp)/", $link)) { 105 // External link 106 107 $lineText = str_replace( 108 $matches[0], 109 '<a href="' . $link . '">' . $name . "</a>", 110 $lineText 111 ); 112 } else { 113 // Internal link 114 115 $lineText = str_replace( 116 $matches[0], 117 html_wikilink($link, $name), 118 $lineText 119 ); 120 } 121 } else { 122 $lineText = preg_replace( 123 "/\*\*([^\*]*)\*\*/", 124 "<b>$1</b>", 125 $lineText 126 ); 127 $lineText = preg_replace("/_([^_]*)_/", "<u>$1</u>", $lineText); 128 $lineText = preg_replace( 129 "/\/\/([^\/]*)\/\//", 130 "<i>$1</i>", 131 $lineText 132 ); 133 } 134 135 return $lineText; 136 } 137 138 /** 139 * 140 * 141 * As an example, it interprets the following source text into 142 * this survey configuration array: 143 * 144 * * Question A 145 * * Answer A-A 146 * * Question A-B 147 * * Answer A-B-A 148 * * Answer A-B-B 149 * * Question B 150 * * Answer B-A 151 * * Answer B-B 152 * 153 * array( 154 * "_name": "root", 155 * "_hasChildren": true, 156 * "_children": array( 157 * array( 158 * "_name": "Question A", 159 * "_hasChildren": true, 160 * "_children": array( 161 * array( 162 * "_name": "Answer A-A", 163 * "_hasChildren": false 164 * ), 165 * array( 166 * "_name": "Question A-B", 167 * "_hasChildren": true, 168 * "_children": array( 169 * array( 170 * "_name": "Answer A-B-A", 171 * "_hasChildren": false 172 * ), 173 * array( 174 * "_name: "Answer A-B-B", 175 * "_hasChildren": false 176 * ) 177 * ) 178 * ) 179 * ) 180 * ), 181 * array( 182 * "_name:"Question B", 183 * "_hasChildren": true, 184 * "_children": array( 185 * array( 186 * "_name": "Answer B-A", 187 * "_hasChildren": false 188 * ), 189 * array( 190 * "_name": "Answer B-B", 191 * "_hasChildren": false 192 * ) 193 * ) 194 * ) 195 * ) 196 * ); 197 * 198 * @param String $syntaxText Syntax text for the survey 199 * @param int $currentLine Current line in the syntax 200 * @param int $currentLevel Current level of survey 201 * 202 * @return Array The survey configuration as a hash 203 */ 204 205 public function interpretSurvey( 206 $syntaxText, 207 $currentLine = 0, 208 $currentLevel = -1 209 ) { 210 $syntaxArray = explode("\n", $syntaxText); 211 212 $returnArray = []; 213 214 if ($currentLevel == -1) { 215 $returnArray["_name"] = "root"; 216 $returnArray["_children"] = []; 217 } else { 218 $workLine = $syntaxArray[$currentLine]; 219 220 preg_match('/^( *) \* (.*)$/', $workLine, $lineMatch); 221 222 $returnArray["_name"] = $this->renderText($lineMatch[2]); 223 $returnArray["_children"] = []; 224 225 $currentLine++; 226 } 227 228 while ($currentLine < count($syntaxArray)) { 229 $workLine = $syntaxArray[$currentLine]; 230 231 preg_match('/^( *) \* (.*)$/', $workLine, $lineMatch); 232 233 $nextLine = $syntaxArray[$currentLine + 1]; 234 235 preg_match('/^( *) \* (.*)$/', $nextLine, $nextLineMatch); 236 237 $lineLevel = strlen($lineMatch[1]) / 2; 238 $nextLineLevel = strlen($nextLineMatch[1]) / 2; 239 240 if ($lineLevel == $nextLineLevel) { 241 // Add a child 242 243 $returnArray["_children"][] = [ 244 "_name" => $this->renderText($lineMatch[2]), 245 "_hasChildren" => false, 246 ]; 247 } elseif ($lineLevel < $nextLineLevel) { 248 // Add a child with children 249 250 $subArray = $this->interpretSurvey( 251 $syntaxText, 252 $currentLine, 253 $lineLevel 254 ); 255 256 $returnArray["_children"][] = $subArray; 257 258 $currentLine = $subArray["_currentLine"]; 259 260 $newNextLine = $syntaxArray[$currentLine + 1]; 261 262 preg_match( 263 '/^( *) \* (.*)$/', 264 $newNextLine, 265 $newNextLineMatch 266 ); 267 268 $newNextLineLevel = strlen($newNextLineMatch[1]) / 2; 269 270 if ($nextLineLevel > $newNextLineLevel + 1) { 271 $returnArray["_hasChildren"] = true; 272 $returnArray["_currentLine"] = $currentLine; 273 274 return $returnArray; 275 } 276 } else { 277 // We're done here. Return. 278 279 // Add a child 280 281 $returnArray["_children"][] = [ 282 "_name" => $this->renderText($lineMatch[2]), 283 "_hasChildren" => false, 284 ]; 285 286 $returnArray["_hasChildren"] = true; 287 $returnArray["_currentLine"] = $currentLine; 288 289 return $returnArray; 290 } 291 292 $currentLine++; 293 } 294 295 // We're through 296 297 if (count($returnArray["_children"]) > 0) { 298 $returnArray["_hasChildren"] = true; 299 } 300 301 $returnArray["_currentLine"] = $currentLine; 302 303 return $returnArray; 304 } 305} 306