1<?php 2if(!defined('DOKU_INC')) die(); 3if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 4require_once(DOKU_PLUGIN.'syntax.php'); 5 6class syntax_plugin_conform extends DokuWiki_Syntax_Plugin 7{ 8 function getInfo() 9 { 10 return array( 11 'author' => 'William Fletcher', 12 'email' => 'uiriamu.furecchaa@gmail.com', 13 'date' => '2008-09-08', 14 'name' => 'conform', 15 'desc' => 'Creates HTML forms properly', 16 'url' => 'http://thirdforces.internationalconspiracy.org/~ultraviolet/software/conform/', 17 ); 18 } 19 20 function getType() 21 { 22 return 'substition'; 23 } 24 25 function getPType() 26 { 27 return 'block'; 28 } 29 30 function getSort() 31 { 32 return 999; 33 } 34 35 function connectTo($mode) 36 { 37 $this->Lexer->addEntryPattern('<CONFORM.*?>(?=.*?</CONFORM>)',$mode,'plugin_conform'); 38 } 39 40 function postConnect() 41 { 42 $this->Lexer->addExitPattern('</CONFORM>', 'plugin_conform'); 43 } 44 45 function handle($match, $state, $pos, &$handler) 46 { 47 switch ($state) 48 { 49 case DOKU_LEXER_UNMATCHED: 50 if ( !$conform =& plugin_load('helper', 'conform') ) return false; 51 return $conform->conformExtract($match); 52 break; 53 } 54 return false; 55 } 56 57 function conformError(&$renderer, $message) 58 { 59 $renderer->doc .= '<span style="color:#FF0000;">'.$message.'</span><br>'; 60 } 61 62 function conformCreateEmailInput($arg) 63 { 64 switch($arg[0]) 65 { 66 case 'Checkbox': 67 if ( isset($_POST["$arg[1]"]) ) 68 { 69 return "Yes"; 70 } 71 else 72 { 73 return "No"; 74 } 75 default: 76 return htmlspecialchars($_POST["$arg[1]"]); 77 } 78 } 79 80 function conformCreateInput($arg) 81 { 82 switch($arg[0]) 83 { 84 case 'Textbox': 85 $textbox = "<input class=\"edit\" type=\"text\" name=\"$arg[1]\" style=\"width:".$arg[3]."px;\""; 86 $textbox .= " value=\"".htmlspecialchars($_POST["$arg[1]"])."\""; 87 $textbox .= ">"; 88 return $textbox; 89 case 'Textarea': 90 $textarea = "<textarea class=\"edit\" name=\"$arg[1]\" rows=\"$arg[3]\" style=\"width:".$arg[4]."px;\">"; 91 $textarea .= htmlspecialchars($_POST["$arg[1]"]); 92 $textarea .= "</textarea>"; 93 return $textarea; 94 break; 95 case 'Checkbox': 96 $checked = ""; 97 if ( isset($_POST["id"]) ) 98 { 99 if ( $_POST["$arg[1]"] == "on" ) $checked = "checked"; 100 } 101 else 102 { 103 if ( $arg[3] == 1 ) $checked = "checked"; 104 } 105 $checkbox = "<input type=\"checkbox\" name=\"$arg[1]\" $checked>"; 106 return $checkbox; 107 break; 108 case 'Radio': 109 $radiocount = 0; 110 if ( ! isset($_POST["$arg[1]"]) ) $checked = " checked='checked'"; 111 foreach ( $arg[3] as $value ) 112 { 113 if ( $value == $_POST["$arg[1]"] ) $checked = " checked='checked'"; 114 $radio .= "<input type=\"radio\" name=\"$arg[1]\" value=\"$value\"$checked>$value<br>"; 115 $checked = ""; 116 } 117 return $radio; 118 break; 119 case 'Select': 120 $select = "<select name=\"$arg[1]\">"; 121 $selected = ""; 122 foreach ( $arg[3] as $value ) 123 { 124 if ( $value == $_POST["$arg[1]"] ) $selected = "selected"; 125 $select .= "<option $selected>$value</option>"; 126 $selected = ""; 127 } 128 $select .= "</select>"; 129 return $select; 130 default: 131 return "ERROR! ERROR! ERROR! Attempting to create an unsupported input maybe?"; 132 } 133 } 134 135 function conformConstraintArgCheck($constraintname, $postname, $constraints, &$renderer) 136 { 137 foreach ( $constraints as $constraint ) 138 { 139 if ( $constraintname == $constraint[1] ) 140 { 141 if ( ! isset($_POST["$postname"]) ) 142 { 143 $this->conformError($renderer, "Constraint $postname checked against a value that wasn't posted!"); 144 return false; 145 } 146 $post = $_POST["$postname"]; 147 $check = explode("=", $constraint[3], 2); 148 if ( ( $check[0] == 'maxLength' && strlen($post) > $check[1] ) || 149 ( $check[0] == 'minLength' && strlen($post) < $check[1] ) ) 150 { 151 $this->conformError($renderer, "$constraint[2]"); 152 return false; 153 } 154 } 155 } 156 return true; 157 } 158 159 function conformConstraintCheck($constraints, $tables, &$renderer) 160 { 161 foreach ( $tables as $table ) 162 { 163 $args = &$table['args']; 164 if ( count($args) == 0 ) continue; 165 switch($table['mode']) 166 { 167 case 0: 168 foreach ( $args as $arg ) 169 { 170 switch($arg[0]) 171 { 172 case 'Submit': 173 case 'Line': 174 case 'Static': 175 case 'Radio': 176 case 'Checkbox': 177 case 'Select': 178 break; 179 default: 180 if ( $this->conformConstraintArgCheck($arg[1], "$arg[1]", $constraints, $renderer) == false ) 181 { 182 $this->conformConstrained = $arg[1]; 183 return false; 184 } 185 } 186 } 187 break; 188 case 1: 189 if ( $table['complete'] == 0 ) break; 190 $rows = $table['rows']; 191 for ( $row = 1; $row <= $rows; $row++ ) 192 { 193 foreach ( $args as $arg ) 194 { 195 switch($arg[0]) 196 { 197 case 'Submit': 198 case 'Line': 199 case 'Static': 200 case 'Radio': 201 case 'Checkbox': 202 case 'Select': 203 break; 204 default: 205 if ( $this->conformConstraintArgCheck($arg[1], "$arg[1]_$row", $constraints, $renderer) == false ) 206 { 207 $this->conformConstrained = $arg[1]; 208 return false; 209 } 210 } 211 } 212 } 213 break; 214 } 215 } 216 return true; 217 } 218 219 function conformCreateDescription($text, $postname) 220 { 221 if ( isset($_POST["id"]) && $postname == $this->conformConstrained ) 222 { 223 return '<span style="color:#FF0000;">'.$text.'</span><br>'; 224 } 225 return $text; 226 } 227 228 function render($format, &$renderer, $data) 229 { 230 global $ID; 231 if( $format == 'xhtml' ) 232 { 233 session_start(); 234 $formaction = DOKU_URL . "doku.php"; 235 $renderer->info['cache'] = false; 236 if ( $data == false ) return false; 237 if ( ! is_array($data) ) return false; 238 if ( ! in_array($ID, $data['idallow']) ) 239 { 240 $this->conformError($renderer, "Conform not allowed on this page! Please ask the admin to rectify this!"); 241 return true; 242 } 243 if ( count($data['errors']) > 0 ) 244 { 245 foreach ( $data['errors'] as $error ) 246 { 247 $this->conformError($renderer, $error); 248 } 249 } 250 $tables = &$data['tables']; 251 $email = false; 252 if ( isset($_POST["id"]) ) 253 { 254 if ( $this->conformConstraintCheck($data['constraints'], $tables, $renderer) == true ) 255 { 256 $email = true; 257 } 258 } 259 if ( $email == false ) 260 { 261 $form .= "<form action=\"$formaction\" method=\"post\" accept-charset=\"utf-8\" enctype=\"multipart/form-data\">\n"; 262 $_SESSION["conform_emailed"] = false; 263 } 264 $form .= "<table class=\"conform\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n"; 265 $maxcolumns = $data['maxcolumns']; 266 if ( $maxcolumns < 2 ) 267 { 268 $columns = 2; 269 $maxcolumns = 2; 270 } 271 else 272 { 273 $columns = $maxcolumns; 274 } 275 foreach ( $tables as $table ) 276 { 277 $args = &$table['args']; 278 if ( count($args) == 0 ) continue; 279 switch($table['mode']) 280 { 281 case 0: 282 foreach ( $args as $arg ) 283 { 284 switch($arg[0]) 285 { 286 case 'Submit': 287 $submit = $arg; 288 break; 289 case 'Line': 290 $form .= "<tr><td colspan=\"$columns\"><br></td></tr>\n"; 291 break; 292 case 'Static': 293 $form .= "<tr><td colspan=\"$columns\">$arg[1]</td></tr>\n"; 294 break; 295 default: 296 if ( $email == false ) 297 { 298 $input = $this->conformCreateInput($arg); 299 } 300 else 301 { 302 $input = $this->conformCreateEmailInput($arg); 303 } 304 $form .= "<tr><td colspan=\"".($columns - 1 ). 305 "\">".$this->conformCreateDescription($arg[2], $arg[1])."</td><td>$input<br></td></tr>\n"; 306 } 307 } 308 break; 309 case 1: 310 if ( $table['complete'] == 0 ) break; 311 $rows = $table['rows']; 312 $argcolumns = $table['columns']; 313 for ( $row = 0; $row <= $rows; $row++ ) 314 { 315 $form .= "<tr>\n"; 316 $argcount = 0; 317 foreach ( $args as $arg ) 318 { 319 switch($arg[0]) 320 { 321 case 'Submit': 322 $submit = $arg; 323 break; 324 case 'Line': 325 break; 326 case 'Static': 327 break; 328 default: 329 $colspan = ""; 330 if ( $argcount == $argcolumns ) $colspan = " colspan=\"".($maxcolumns - $argcolumns)."\""; 331 if ( $row > 0 ) 332 { 333 $arg[1] .= "_$row"; 334 if ( $email == false ) 335 { 336 $input = $this->conformCreateInput($arg); 337 } 338 else 339 { 340 $input = $this->conformCreateEmailInput($arg); 341 } 342 $form .= "<td$colspan>$input<br></td>\n"; 343 } 344 else 345 { 346 $form .= "<td$colspan>".$this->conformCreateDescription($arg[2], $arg[1])."</td>\n"; 347 } 348 } 349 $argcount++; 350 } 351 $form .= "</tr>\n"; 352 } 353 break; 354 } 355 } 356 if ( count($data['errors']) == 0 && $email == false ) 357 { 358 $form .= "<tr><td colspan=\"$maxcolumns\"><input class=\"button\" type=\"submit\" name=\"submit\" value=\"$submit[1]\""; 359 $form .= "style=\"width:".$submit[2]."px;\"></td></tr>\n"; 360 $form .= "<input type=\"hidden\" name=\"id\" value=\"$ID\" />\n"; 361 $form .= "</form>"; 362 } 363 $form .= "</table>\n"; 364 if ( $email == true ) 365 { 366 $theboundary = md5(uniqid("")); 367 $header = "From: ".$this->getConf('conformFrom'); 368 $header .= "\r\nMIME-Version: 1.0"; 369 $header .= "\nContent-Type: text/html"; 370 $header .= "\r\nX-Priority: 3"; 371 $header .= "\r\nX-MSMail-Priority: Normal"; 372 $header .= "\r\n"; 373 if ( $_SESSION["conform_emailed"] == false ) 374 { 375 $emailform = "<html><body>"; 376 $emailform .= "<style>"; 377 $emailform .= "body { padding: 0; border-spacing: 0; border-collapse: collapse; }"; 378 $emailform .= "table.conform { border: 1px solid #000000; padding: 0px; margin: 5px; border-spacing: 0; }"; 379 $emailform .= "table.conform td { border: 1px solid #000000; padding 0px; margin: 5px; border-spacing: 0; }"; 380 $emailform .= "</style>"; 381 $emailform .= $form; 382 $emailform .= "</body></html>"; 383 mail($data['to'], $data['subject'], $emailform, $header); 384 } 385 $_SESSION["conform_emailed"] = true; 386 } 387 $renderer->doc .= $form; 388 return true; 389 } 390 return false; 391 } 392} 393?> 394