1<?php 2/** 3 * formular Plugin: Displays Forms 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Ole Rienow <wikiform@rienow.eu> 7 * 8 */ 9 10/** 11 * Changes Log 12 * [2008-01-09] Original Form Plugin from Ole Rienow 13 * [2008-02-17] Small additions by Stephane Chamberland <stephane.chamberland@gmail.com> 14 * - rename to Formular (not to confuse with Esther's Form plugin) and to keep compatibility with previous versions settings 15 * - make compatible with configuration plugin 16 * - localize [include only the En, Fr translations] 17 * - add default styles [borrowed from Esther's form plugin] 18 * [2008-06-29] You can hand over GET-Parameters as Standard Values for Textfields and Textareas 19 * [2008-07-03] 20 * - Many Refactorings 21 * - Constraints are now also possible for self written Scripts 22 * - Username in Mail 23 * - Added Grepnot Constraint 24 * [2008-07-09] 25 * - Added local wikipage Language (e.g. Hidden lang "en";) 26 * [2008-07-17] 27 * - Added Debug-Modus 28 * - Bugfix in the Constraint-Writer for self written Scripts 29 * [2008-07-18] 30 * - Bugfix in MailForm creation 31 * - Added Feature to hold Data if given Data is not valid 32 * [2008-07-19] 33 * - Added File-Upload feature 34 * [2008-07-20] 35 * - Hold Data in Selectboxes, Radiobuttons and Checkboxes as well 36 * - Bugfix for Multiple Line Data in Textareas 37 * [2008-07-23] 38 * - Writing Debug-Infos to File 39 * [2009-03-12] 40 * - little bugfix of missing quotation mark in textareas 41 * - new italian translation - thanks to Diego Pierotto 42 */ 43 44/**$renderer->info['cache'] = false; 45 * Configuration specified in DOKUPATH/conf/local.php 46 * 47 * $conf['plugin']['formular']['AllowInclude'] = 1|0; 48 * $conf['plugin']['formular']['mailPath'] = "data/formplugin/"; 49 * $conf['plugin']['formular']['selectPage'] = "formplugin:select"; 50 * $conf['plugin']['formular']['mailSubject'] = "Message -- formular plugin"; 51 * $conf['plugin']['formular']['mailFrom'] = ""; 52 * 53 */ 54 55if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 56if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 57require_once(DOKU_PLUGIN.'syntax.php'); 58 59/** 60 * All DokuWiki plugins to extend the parser/rendering mechanism 61 * need to inherit from this class 62 */ 63class syntax_plugin_formular extends DokuWiki_Syntax_Plugin { 64 65 var $scriptPath; 66 var $mailPath; 67 var $mailFile; 68 var $internalScript = false; 69 var $localLang = array(); 70 71 /** 72 * return some info 73 */ 74 function getInfo(){ 75 return array( 76 'author' => 'Ole Rienow', 77 'email' => 'wikiform@rienow.eu', 78 'date' => '2009-03-12', 79 'name' => 'Formular Plugin', 80 'desc' => 'Creates HTML Forms', 81 'url' => 'http://wiki.splitbrain.org/plugin:form', 82 ); 83 } 84 85 function getType(){ 86 return 'substition'; 87 } 88 89 /** 90 * What about paragraphs? (optional) 91 */ 92 function getPType(){ 93 return 'block'; 94 } 95 96 /** 97 * Where to sort in? 98 */ 99 function getSort(){ 100 return 999; 101 } 102 103 /** 104 * Connect pattern to lexer 105 */ 106 function connectTo($mode) { 107 $this->Lexer->addEntryPattern('<FORM.*?>(?=.*?</FORM>)',$mode,'plugin_formular'); 108 } 109 110 function postConnect() { 111 $this->Lexer->addExitPattern('</FORM>', 'plugin_formular'); 112 } 113 114 function phpParsed($string) { 115 require_once DOKU_INC . 'inc/parser/xhtml.php'; 116 require_once DOKU_INC . 'inc/parser/parser.php'; 117 118 $Parser = & new Doku_Parser(); 119 $Parser->Handler = & new Doku_Handler(); 120 $Parser->addMode('php',new Doku_Parser_Mode_PHP()); 121 122 $instructions = $Parser->parse($string); // Get a list of instructions 123 $Renderer = & new Doku_Renderer_XHTML(); // Create a renderer 124 125 // Loop through the instructions 126 foreach ( $instructions as $instruction ) { 127 call_user_func_array(array(&$Renderer, $instruction[0]),$instruction[1]); 128 } 129 130 return trim(substr($Renderer->doc, 4, -5)); 131 } 132 133 function parsed($string) { 134 require_once DOKU_INC . 'inc/parser/xhtml.php'; 135 require_once DOKU_INC . 'inc/parser/parser.php'; 136 137 $Parser = & new Doku_Parser(); 138 $Parser->Handler = & new Doku_Handler(); 139 140 $Parser->addMode('listblock',new Doku_Parser_Mode_ListBlock()); 141 $Parser->addMode('preformatted',new Doku_Parser_Mode_Preformatted()); 142 $Parser->addMode('notoc',new Doku_Parser_Mode_NoToc()); 143 $Parser->addMode('header',new Doku_Parser_Mode_Header()); 144 $Parser->addMode('table',new Doku_Parser_Mode_Table()); 145 $Parser->addMode('linebreak',new Doku_Parser_Mode_Linebreak()); 146 $Parser->addMode('footnote',new Doku_Parser_Mode_Footnote()); 147 $Parser->addMode('hr',new Doku_Parser_Mode_HR()); 148 $Parser->addMode('unformatted',new Doku_Parser_Mode_Unformatted()); 149 $Parser->addMode('php',new Doku_Parser_Mode_PHP()); 150 $Parser->addMode('html',new Doku_Parser_Mode_HTML()); 151 $Parser->addMode('code',new Doku_Parser_Mode_Code()); 152 $Parser->addMode('file',new Doku_Parser_Mode_File()); 153 $Parser->addMode('quote',new Doku_Parser_Mode_Quote()); 154 $Parser->addMode('acronym',new Doku_Parser_Mode_Acronym(array_keys(getAcronyms()))); 155 $Parser->addMode('multiplyentity',new Doku_Parser_Mode_MultiplyEntity()); 156 $Parser->addMode('quotes',new Doku_Parser_Mode_Quotes()); 157 $Parser->addMode('camelcaselink',new Doku_Parser_Mode_CamelCaseLink()); 158 $Parser->addMode('internallink',new Doku_Parser_Mode_InternalLink()); 159 $Parser->addMode('media',new Doku_Parser_Mode_Media()); 160 $Parser->addMode('externallink',new Doku_Parser_Mode_ExternalLink()); 161 $Parser->addMode('windowssharelink',new Doku_Parser_Mode_WindowsShareLink()); 162 $Parser->addMode('filelink',new Doku_Parser_Mode_FileLink()); 163 $Parser->addMode('eol',new Doku_Parser_Mode_Eol()); 164 165 $formats = array ( 166 'strong', 'emphasis', 'underline', 'monospace', 167 'subscript', 'superscript', 'deleted', 168 ); 169 foreach ($formats as $format) { 170 $Parser->addMode($format,new Doku_Parser_Mode_Formatting($format)); 171 } 172 173 $instructions = $Parser->parse($string); // Get a list of instructions 174 $Renderer = & new Doku_Renderer_XHTML(); // Create a renderer 175 176 // Loop through the instructions 177 foreach ( $instructions as $instruction ) { 178 call_user_func_array(array(&$Renderer, $instruction[0]),$instruction[1]); 179 } 180 181 return trim(substr($Renderer->doc, 4, -5)); 182 } 183 184 function setLocalLang($text) { 185 $langFile = DOKU_PLUGIN . "formular/lang/$text/lang.php"; 186 if (is_File($langFile)) { 187 include($langFile); 188 $this->localLang = $lang; 189 } 190 } 191 192 function getLocalLang($id) { 193 return (isset($this->localLang[$id])) ? 194 $this->localLang[$id] : $this->getLang($id); 195 } 196 197 /** 198 * Function to create some Error-Output 199 */ 200 function insertError($name, $type=3){ 201 $header = '<tr><td colspan="2"><span style="color:#FF0000;">'; 202 $footer = '</span></td></tr>'; 203 switch ($type) { 204 case 0: 205 $error = $this->getLocalLang('name_not_unique').': ' . trim($name); 206 break; 207 case 1: 208 $error = $this->getLocalLang('wrong_nb_of_arguments').': ' . trim($name); 209 break; 210 case 2: 211 $error = $this->getLocalLang('undef_combo').': ' . trim($name); 212 break; 213 case 3: 214 $error = trim($name); 215 break; 216 } 217 return $header.$error.$footer; 218 } 219 220 /** 221 * Function to write something at beginning of file 222 */ 223 function writeBefore($file, $content) { 224 if (!file_exists($file)) { 225 $handle = fopen($file,'w'); 226 fclose($handle); 227 } 228 229 $fOld = file_get_contents($file); 230 $newContent = $content.$fOld; 231 $f = fopen($file,'w') or die($this->getLocalLang('cannot_open')); 232 fwrite($f, $newContent); 233 fclose($f); 234 // file_put_contents($file, $newContent); not used because not implemented below php5 235 } 236 237 function writeDebugInfo($message) { 238 if ($this->getConf('DebugMode')) { 239 $this->writeBefore(DOKU_PLUGIN.'formular/debug.txt', $message."\n"); 240 } 241 } 242 243 function constraintError($error) { 244 return "{ \n" 245 . ' $back .= "error='.$error."\";\n" 246 . ' header("Location: $back");' 247 . ' exit();' 248 ."\n}\n"; 249 } 250 251 /** 252 * At the moment this just works if the settings are set as follows: 253 * Use Nice URLs = 2 (DokuWiki Internal) 254 * Use Slash as Namespace seperator = 0 (Not Checked) 255 */ 256 function writeConstraintsToScript() { 257 $this->writeDebugInfo("Function: writeConstraintsToScript"); 258 259 global $conf; 260 if ($conf['userewrite'] != 2 || $conf['useslash'] == 1) { 261 unlink($this->mailPath.'constraint.tmp'); 262 $this->writeDebugInfo("Wrong Settings for this."); 263 return; 264 } 265 266 if ($this->internalScript && file_exists($this->mailPath.'constraint.tmp')) { 267 $sgn_begin = "// Formular Plugin - Constraint Signature Begin"; 268 $sgn_end = "// Formular Plugin - Constraint Signature End"; 269 $sgn_warning = "// Don't remove these lines! Removing can lead to Data Loss in this File!"; 270 271 chdir("lib/"); // To ignore the ../ which is used for niceURLs 272 $this->writeDebugInfo("Current Directory: ".getcwd()); 273 if(isset($this->scriptPath) && $this->scriptPath != '' && file_exists($this->scriptPath)) { 274 $this->writeDebugInfo("Writing from: ../".$this->mailPath."constraint.tmp to: $this->scriptPath"); 275 $constraints = file_get_contents("../".$this->mailPath.'constraint.tmp'); 276 $constraints = "<?php \n" 277 . $sgn_begin . "\n" 278 . $sgn_warning . "\n" 279 . $this->getBackLinkVariable() . "\n" 280 . $constraints . "\n" 281 . $sgn_end . "\n ?>\n"; 282 283 $lines = file($this->scriptPath); 284 $position_bgn = array_search($sgn_begin."\n", $lines); 285 $position_end = array_search($sgn_end."\n", $lines); 286 if($position_bgn != false && $position_end != false) { 287 array_splice($lines, $position_bgn-1, $position_end-$position_bgn+3); 288 } 289 290 foreach ($lines as $line) { 291 $original_file .= $line; 292 } 293 $file = fopen($this->scriptPath,'w') or die($this->getLocalLang('cannot_open')); 294 fwrite($file, $constraints . $original_file); 295 fclose ($file); 296 //file_put_contents($this->scriptPath, $constraints . $original_file); not used because not implemented below php5 297 } else { 298 $this->writeDebugInfo("Error: ScriptPath not set or File Does not Exist - ScriptPath: $this->scriptPath"); 299 } 300 chdir("../"); 301 } else { 302 $this->writeDebugInfo("Error: InternalScript: $this->internalScript - Constraint-File: $this->mailPath constraint.tmp"); 303 } 304 unlink($this->mailPath.'constraint.tmp'); 305 } 306 307 function createMailForm($match) { 308 $this->writeDebugInfo("Creating MailForm"); 309 $daten = explode(" ", substr($match, 13, -1)); 310 $receipt=$daten[0]; 311 $args = explode('"', substr($match, 13, -1)); 312 313 // Parameter PHP used? 314 if ($this->getConf('AllowInclude')) { 315 $phpPos = strpos($match, 'PHP:'); 316 if ($phpPos !== false) { 317 $include = "include(\"" 318 .substr($match, $phpPos +5, strpos($match, '"', $phpPos+5) - ($phpPos+5)) 319 ."\");\n"; 320 $f = fopen($this->mailPath.'incl.tmp','w') or die($this->getLocalLang('cannot_open')); 321 fwrite($f, $include); 322 fclose($f); 323 } else { 324 $include = ''; 325 } 326 } 327 328 if (isset($_SERVER["SCRIPT_URI"])) { 329 $URI = $_SERVER["SCRIPT_URI"] . "?id="; 330 } else { 331 $URI = "http://" . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"] . "?id="; 332 } 333 334 // Parameter Next used? 335 $nextPos = strpos($match, 'NEXT:'); 336 if ($nextPos !== false) { 337 $next = substr($match, $nextPos +6 , strpos($match, '"', $nextPos+6) - ($nextPos+6)); 338 } 339 if (substr($next, 0, 4) == "www.") { 340 $next = "http://" . $next; 341 } elseif (substr($next, 0, 7) == "http://") { 342 $next = $next; 343 } else { 344 $next = $URI.$next; 345 } 346 347 $mail = 'if ($_POST[\'submit\'] == true) { '. " \n" . 348 '$date=date(\'d.m.Y\'); '. " \n" . 349 '$time=date(\'H,i,s\'); '. " \n" . 350 '$receipt=\'' . $receipt . "'; \n" . 351 '$next="' . $next . "\"; \n" . 352 '$string="'.$this->getLang('received_on').' $date : $time: "'; 353 $f = fopen($this->mailPath . 'mail.tmp','w') or die($this->getLocalLang('cannot_open')); 354 fwrite($f, $mail); 355 fclose($f); 356 } 357 358 function createConstraints($line, $name, $error) { 359 $grepPos = strpos($line, 'grep='); 360 $grepnotPos = strpos($line, 'grepnot='); 361 $minLengthPos = strpos($line, 'minLength='); 362 $maxLengthPos = strpos($line, 'maxLength='); 363 $valueTypePos = strpos($line, 'valueType='); 364 $evalFunctionPos = strpos($line, 'evalFunction='); 365 $lengthPos = strpos($line, 'length='); 366 $grepnotPos = strpos($line, 'grepnot='); 367 368 if ($grepPos !== false) { 369 $grep = substr($line, $grepPos+6 , 370 strpos($line, '"', $grepPos+6) - ($grepPos+6)); 371 $constraint .= 'if (! preg_match(\''.$grep.'\', $_POST[\''.$name.'\']))'."\n" 372 .$this->constraintError($error); 373 } 374 if($grepnotPos !== false) { 375 $grepnot = substr($line, $grepnotPos+9 , 376 strpos($line, '"', $grepnotPos+9) - ($grepnotPos+9)); 377 $constraint .= 'if(preg_match(\'' . $grepnot . '\', $_POST[\'' . $name . '\']))' . "\n" 378 .$this->constraintError($error); 379 } 380 if ($lengthPos !== false) { 381 (int) $length = substr($line, $lengthPos+8 , 382 strpos($line, '"', $lengthPos+8) - ($lengthPos+8)); 383 if (! is_numeric($length)) { 384 $data .= $this->insertError($this->getLocalLang('len_not_num')); 385 } 386 $constraint .= 'if (strlen($_POST[\''.$name.'\']) != '.$length.')'."\n" 387 .$this->constraintError($error); 388 } 389 if ($minLengthPos !== false) { 390 (int) $minLength = substr($line, $minLengthPos+11 , 391 strpos($line, '"', $minLengthPos+11) - ($minLengthPos+11)); 392 if (! is_numeric($minLength)) { 393 $data .= $this->insertError($this->getLocalLang('minlen_not_num')); 394 } 395 $constraint .= 'if (strlen($_POST[\''.$name.'\']) < '.$minLength.')'."\n" 396 .$this->constraintError($error); 397 } 398 if ($maxLengthPos !== false) { 399 (int) $maxLength = substr($line, $maxLengthPos+11 , 400 strpos($line, '"', $maxLengthPos+11) - ($maxLengthPos+11)); 401 if (! is_numeric($maxLength)) { 402 $data .= $this->insertError($this->getLocalLang('maxlen_not_num')); 403 } 404 $constraint .= 'if (strlen($_POST[\'' . $name . '\']) > '.$maxLength.')'."\n" 405 .$this->constraintError($error); 406 } 407 if ($valueTypePos !== false) { 408 $valueType = substr($line, $valueTypePos+11 , 409 strpos($line, '"', $valueTypePos+11) - ($valueTypePos+11)); 410 switch ($valueType) { 411 case 'integer' : 412 $constraint .= 'if( (! preg_match("/^\d+$/", $_POST[\''.$name.'\'])) ' 413 .'|| (! is_numeric($_POST[\'' . $name . '\'])) )'."\n" 414 . $this->constraintError($error); 415 break; 416 case 'float' : 417 $constraint .= 'if(! is_numeric($_POST[\''.$name.'\']))'."\n " 418 .$this->constraintError($error); 419 break; 420 case 'eMail' : 421 $constraint .= '$pattern = "/^[A-z0-9\._-]+@[A-z0-9][A-z0-9-]*(\.[A-z0-9_-]+)*\.([A-z]{2,6})$/";'; 422 $constraint .= "\n" 423 .'if (! preg_match($pattern, $_POST[\''.$name.'\']))'."\n" 424 .$this->constraintError($error); 425 break; 426 } 427 } 428 if($grepnotPos !== false) { 429 $grepnot = substr($line, $grepnotPos+9 , strpos($line, '"', $grepnotPos+9) - ($grepnotPos+9)); 430 $constraint .= 'if(preg_match(\'' . $grepnot . '\', $_POST[\'' . $name . '\']))' . "\n" 431 . $this->constraintError($error); 432 } 433 434 if ($this->getConf('AllowInclude')) { 435 if ($evalFunctionPos !== false) { 436 $evalFunction = substr($line, $evalFunctionPos+14 , 437 strpos($line, '"', $evalFunctionPos+14) - ($evalFunctionPos+14)); 438 $constraint .= 'if(! '.$evalFunction.'($_POST[\''.$name.'\']))'."\n" 439 .$this->constraintError($error); 440 } 441 } 442 443 return $constraint; 444 } 445 446 function createFileElement($text, $width, $value) { 447 $result = '<tr><td>' 448 .$this->parsed($text) 449 .'</td><td>' 450 .'<input class="edit" type="file" size="50" ' 451 .'name="file[formular][]"'; 452 453 if(isset($width) and $width != "") { 454 $result .= ' style="width:'.$width.'px;"'; 455 } 456 if(isset($value) and $value != "") { 457 $result .= ' value="' . $value . '"'; 458 } 459 460 $result .= ' /></td></tr>'; 461 return $result; 462 } 463 464 function createTextbox($name, $text, $width, $value) { 465 $result = '<tr><td>' 466 .$this->parsed($text) 467 .'</td><td>' 468 .'<input class="edit" type="text" ' 469 ."name=\"$name\""; 470 471 if(isset($width) and $width != "") { 472 $result .= ' style="width:'.$width.'px;"'; 473 } 474 if(isset($value) and $value != "") { 475 $result .= 'value="' . $value . '"'; 476 } 477 478 $result .= ' /></td></tr>'; 479 return $result; 480 } 481 482 function createHidden($name, $text) { 483 if ($name == 'lang') { 484 $this->setLocalLang($text); 485 } 486 return '<input type="hidden" ' 487 .'name="'.$name 488 .'" value="'.$this->phpParsed($text).'" />'; 489 } 490 491 function createPassbox($name, $text, $width) { 492 $result = '<tr><td>' 493 .$this->parsed($text) 494 .'</td><td>' 495 .'<input class="edit" type="password" ' 496 ."name=\"$name\""; 497 498 if(isset($width) and $width != "") { 499 $result .= ' style="width:'.$width.'px;"'; 500 } 501 $result .= ' /></td></tr>'; 502 return $result; 503 } 504 505 function createSelectBox($name, $text, $width, $options, $value) { 506 $result = '<tr><td>' 507 . $this->parsed($text) 508 .'</td><td>' 509 .'<select name="' . $name . '" size="1"'; 510 511 if(isset($width) and $width != "") { 512 $result .= ' style="width:'.$width.'px;"'; 513 } 514 515 $result .= '><option value="n/a">[ '.$this->getLocalLang('pls_choose').' ]</option>'; 516 517 $first = ''; 518 // create Options 519 foreach ($options as $option) { 520 if(trim($option) == trim($value)) { 521 $checked = 'selected'; 522 } else { 523 $checked = ''; 524 } 525 526 // this is for escape sequences 527 if ($option[strlen($option)-1] == "\\" && $first != '') { 528 $first = $first . ',' . substr($option, 0, -1); 529 } else if ($option[strlen($option)-1] == "\\" && $first == '') { 530 $first = substr($option, 0, -1); 531 } else if ($option[strlen($option)-1] != "\\" && $first != '') { 532 $result .= "<option $checked>".$first.','.$option."</option>"; 533 $first = ''; 534 } else if ($option[strlen($option)-1] != "\\" && $first == '') { 535 $result .= "<option $checked>".$option."</option>"; 536 } 537 } 538 539 $result .= '</select></td></tr>'; 540 return $result; 541 } 542 543 function createTextarea($name, $text, $value, $rows, $width) { 544 $result = '<tr><td>' 545 .$this->parsed($text) 546 .'</td><td>' 547 .'<textarea class="edit" name="'.$name 548 .'" rows="'.$rows.'"'; 549 550 if(isset($width) and $width != "") { 551 $result .= ' style="width:'.$width.'px;"'; 552 } 553 $result .= '>'; 554 if(isset($value) and $value != "") { 555 $result .= str_replace("<br/>",chr(13).chr(10),$value); 556 } 557 $result .= '</textarea></td></tr>'; 558 559 return $result; 560 } 561 562 function createRadioButton($name, $text, $options, $value) { 563 foreach ($options as $option) { 564 // first is for escape sequence to print commata 565 $first = ''; 566 $header = ''; 567 568 if ($option[strlen($option)-1] == "\\") { 569 $first = substr($option, 0, -1); 570 continue; 571 } 572 if ($first != '') { 573 $first = $first.","; 574 $i = 1; 575 } else { 576 $i = 0; 577 } 578 579 if (trim($option) == trim($value) || trim($first.$option) == trim($value)) { 580 $checked = 'checked="checked"'; 581 } else { 582 $checked = ''; 583 } 584 // Is this the first Option? If first is set the first Option has the index 1 not 0 585 if ($option == $options[$i]) { 586 if ($value=='') $checked = 'checked="checked"'; 587 $header = $this->parsed($text); 588 } 589 590 $result .= '<tr><td>'.$header.'</td><td>' 591 .'<input type="radio" name="'.$name 592 .'" value="'.$first.$option.'" ' 593 .$checked.'> ' 594 .$first.$option 595 .'</td></tr>'; 596 } 597 return $result; 598 } 599 600 function setMailFile() { 601 $this->writeDebugInfo("Function: setMailFile()"); 602 global $ID; 603 $mailFilePath = $this->getConf('mailPath'); 604 if (! is_dir($mailFilePath)) mkdir($mailFilePath, 0777); 605 606 // support namespaces 607 $idSplit = explode(":", $ID); 608 if (count($idSplit) > 1) { 609 for ($i = 1; $i < count($idSplit); $i++) { 610 $mailFilePath .= $idSplit[($i-1)] . "/"; 611 if (! is_dir($mailFilePath)) mkdir($mailFilePath, 0777); 612 } 613 $this->mailFile = $mailFilePath . "form_" . $idSplit[$i-1] . ".php"; 614 } else { 615 $this->mailFile = $mailFilePath . "form_" . $ID . ".php"; 616 } 617 $this->mailPath = $mailFilePath; 618 $this->writeDebugInfo("MailPath: $mailFilePath"); 619 $this->writeDebugInfo("MailFile: $this->mailFile"); 620 } 621 622 function getFileUploadScript() { 623 return '$boundary = strtoupper(md5(uniqid(time())));' . "\n" 624 . '$mail_header = "From: '.$this->getConf('mailFrom').'\n";' . "\n" 625 . '$mail_header .= "MIME-Version: 1.0";' . "\n" 626 . '$mail_header .= "\nContent-Type: multipart/mixed; boundary=$boundary";' . "\n" 627 . '$mail_header .= "\n\nThis is a multi-part message in MIME format -- Dies ist eine mehrteilige Nachricht im MIME-Format";' . "\n" 628 . '$mail_header .= "\n--$boundary";' . "\n" 629 . '$mail_header .= "\nContent-Type: text/plain";' . "\n" 630 . '$mail_header .= "\nContent-Transfer-Encoding: 8bit";' . "\n" 631 . '$mail_header .= "\n\n$string";' . "\n" 632 . '$i = 0;' . "\n" 633 . 'while (is_uploaded_file($_FILES[\'file\'][\'tmp_name\'][\'formular\'][$i])) {' . "\n" 634 . ' if ($_FILES[\'file\'][\'size\'][\'formular\'][$i] > ($_POST[\'file_maxsize\'] * 1000000)) {' . "\n" 635 . ' $back .= "error='.$this->getLocalLang('filesize_exceeded').'";' . "\n" 636 . ' header("Location: $back");' . "\n" 637 . ' exit();' . "\n" 638 . ' }' . "\n" 639 . ' $file_content = fread(fopen($_FILES[\'file\'][\'tmp_name\'][\'formular\'][$i],"r"),$_FILES[\'file\'][\'size\'][\'formular\'][$i]);' . "\n" 640 . ' //$file_content = readfile($_FILES[\'file\'][\'tmp_name\'][\'formular\'][$i]);' . "\n" 641 . ' $file_content = chunk_split(base64_encode($file_content));' . "\n" 642 . ' $mail_header .= "\n--$boundary";' . "\n" 643 . ' $mail_header .= "\nContent-Type: ".$_FILES[\'file\'][\'type\'][\'formular\'][$i]."; name=\"".$_FILES[\'file\'][\'name\'][\'formular\'][$i]."\"";' . "\n" 644 . ' $mail_header .= "\nContent-Transfer-Encoding: base64";' . "\n" 645 . ' $mail_header .= "\nContent-Disposition: attachment; filename=\"".$_FILES[\'file\'][\'name\'][\'formular\'][$i]."\"";' . "\n" 646 . ' $mail_header .= "\n\n$file_content";' . "\n" 647 . ' $i++;' . "\n" 648 . '}' . "\n" 649 . '$mail_header .= "\n--$boundary--";' . "\n"; 650 } 651 652 // create Constraints Backlink 653 function getBackLinkVariable() { 654 return '$back = $_POST["formular_url"]."?";' 655 . "\n".'$blacklist=array("next","formular_url","submit","error","file_maxsize");' 656 . "\n".'foreach($_POST as $key_name => $key_value) {' 657 . "\n".' if (in_array($key_name, $blacklist)) continue;' 658 . "\n".' $key_value = str_replace(chr(10),"<br/>",$key_value);' 659 . "\n".' $key_value = str_replace(chr(13),"",$key_value);' 660 . "\n".' $back .= $key_name . "=". utf8decode($key_value) . "&";' 661 . "\n}\n"; 662 } 663 664 //Only for Internal USE! 665 function printAllInternInformation() { 666 echo "\nMETHODS: \n"; 667 print_r(get_class_methods($this)); 668 echo "\nMETHODS-END: \n"; 669 echo "\nVARIABLES: \n"; 670 print_r(get_object_vars($this)); 671 echo "\nVARIABLES-END: \n"; 672 echo "\nGLOBALS: \n"; 673 print_r($GLOBALS); 674 echo "\nGLOBALS-END: \n"; 675 } 676 677 /** 678 * Handle the match 679 */ 680 function handle($match, $state, $pos, &$handler) { 681 global $ID; 682 683 switch ($state) { 684 case DOKU_LEXER_ENTER : 685 $this->writeDebugInfo("DOKU_LEXER_ENTER"); $this->writeDebugInfo("WorkingDirectory: ".getcwd()); 686 $this->setMailFile(); 687 // MAILTO-Formular 688 if (substr($match, 6, 7) == "MAILTO:") { 689 $this->createMailForm($match); 690 $action = DOKU_URL . $this->mailFile; 691 } else { 692 $args = explode('"', $match); 693 //DOKUWIKI-PAGE 694 if ((substr($args[1], 0, 7) != "http://") 695 && (substr($args[1], -4, 4) != ".php") 696 && (substr($args[1], 0, 3) != "www")) { 697 $this->scriptPath = "doku.php?id=" . $args[1]; 698 //External Link without HTTP 699 } elseif (substr($args[1], 0, 4) == "www.") { 700 $this->scriptPath = "http://". $args[1]; 701 //External Link with HTTP 702 } elseif (substr($args[1], 0, 7) == "http://") { 703 $this->scriptPath = $args[1]; 704 // Internal PHP-Script-Path 705 } elseif (substr($args[1], -4, 4) == ".php") { 706 $this->scriptPath = $args[1]; 707 $this->internalScript = true; 708 } else { 709 $this->scriptPath = $args[1]; 710 } 711 712 $this->writeDebugInfo("ScriptPath: $this->scriptPath"); 713 $action = $this->scriptPath; 714 } 715 $data = "<form action=\"$action\" method=\"post\" accept-charset=\"utf-8\" " 716 . "enctype=\"multipart/form-data\"> <table class=\"formular\">"; 717 718 if (isset($_GET['error'])) { 719 $data .= '<tr><td colspan="2"><span style="color:#FF0000;">' 720 . $_GET['error'] 721 . '</span></td></tr>'; 722 } 723 $data .= $this->createHidden("formular_url", DOKU_URL."doku.php/".$ID); 724 break; 725 726 case DOKU_LEXER_EXIT : 727 $this->writeDebugInfo("DOKU_LEXER_EXIT_BEGIN"); 728 $data = '</table></form>'; 729 if (is_file($this->mailPath.'mail.tmp')) { 730 $subject = $this->getConf('mailSubject'); 731 $mail = '; '." \n" 732 . '$string .= "\nSender: ".$_SERVER[\'LOGON_USER\'].$_SERVER[\'REMOTE_USER\'];'." \n"; 733 $mail .= $this->getFileUploadScript(); 734 $mail .= 'mail($receipt, \''.$subject.'\', "", $mail_header);' 735 . " \n" 736 . 'header("Location: $next"); ' 737 . " \n } \n ?>"; 738 739 $f = fopen($this->mailPath.'mail.tmp','a') or die($this->getLocalLang('cannot_open')); 740 fwrite($f, $mail); 741 fclose($f); 742 743 $mailhead = "<?php\n"; 744 if (is_file($this->mailPath.'incl.tmp')) { 745 $mailhead .= file_get_contents($this->mailPath.'incl.tmp'); 746 unlink($this->mailPath.'incl.tmp'); 747 } 748 // create Constraints Backlink 749 $mailhead .= $this->getBackLinkVariable(); 750 751 $this->writeBefore ($this->mailPath.'mail.tmp', $mailhead); 752 $this->writeDebugInfo("Copy From ".$this->mailPath.'mail.tmp - To: '.$this->mailFile); 753 copy($this->mailPath.'mail.tmp', $this->mailFile); 754 unlink($this->mailPath.'mail.tmp'); 755 // Write Constraints to self written Script-Files 756 } elseif(is_file($this->mailPath.'constraint.tmp')) { 757 $this->writeConstraintsToScript(); 758 } 759 $this->writeDebugInfo("DOKU_LEXER_EXIT_END"); 760 break; 761 762 // Complete Body between <FORM> and </FORM> 763 default: 764 $lines = explode(';', $match); 765 // This is for global ; escape sequence 766 foreach ($lines as $index => $line){ 767 if (isset($firstPart) && $firstPart != '') { 768 $lines[$index] = $firstPart.$line; 769 $line = $lines[$index]; 770 unset($firstPart); 771 } 772 if (substr($line, -1) == '\\') { 773 $firstPart = substr($line, 0, -1).';'; 774 unset($lines[$index]); 775 continue; 776 } 777 } 778 $nameArray = array(); 779 780 foreach ($lines as $line) { 781 $explBlank = explode(' ', $line); 782 $explQuoteMark = explode('"', $line); 783 $lastArgs = explode(' ', trim($explQuoteMark[count($explQuoteMark)-1])); 784 $name = trim($explBlank[1]); 785 $text = trim($explQuoteMark[1]); 786 $value = $_GET["$name"]; 787 788 // Keyword 789 switch (trim($explBlank[0])) { 790 case 'Textbox': 791 case 'Passbox': 792 case 'Hidden' : 793 // number of arguments given is correct? 794 if (count($explQuoteMark) != 3 || count($explBlank) < 2) { 795 $data .= $this->insertError($name, 1); 796 break; 797 } 798 // routine to check if names are unique 799 if (in_array($name, $nameArray)) { 800 $data .= $this->insertError($name, 0); 801 break; 802 } 803 array_push($nameArray, $name); 804 805 $width = $lastArgs[0]; 806 if (trim($explBlank[0]) == 'Textbox') { 807 $data .= $this->createTextbox($name, $text, $width, $value); 808 } elseif (trim($explBlank[0]) == 'Passbox') { 809 $data .= $this->createPassbox($name, $text, $width); 810 } else { 811 $data .= $this->createHidden($name, $text); 812 } 813 if (is_file($this->mailPath.'mail.tmp')) { 814 $mail .= " . \"\\n $name ==> \" . \$_POST['$name'] " . "\n"; 815 } 816 break; 817 818 case 'Select' : 819 // SelectBox with manual Options given by a list 820 if (count($explQuoteMark) == 5 821 && count(explode(' ', trim($explQuoteMark[4]))) == 1 822 && count(explode(' ', trim($explQuoteMark[0]))) == 2 823 && trim($explQuoteMark[2]) == '' ) { 824 $width = $lastArgs[0]; 825 $optionsList = $explQuoteMark[3]; 826 $options = explode(",", $optionsList); 827 } 828 // SelectBox defined in wikipage select 829 elseif (count($explQuoteMark) == 3 830 && count(explode(' ', trim($explQuoteMark[0]))) == 2 831 && (count(explode(' ', trim($explQuoteMark[2]))) == 2 832 || count(explode(' ', trim($explQuoteMark[2]))) == 1)) { 833 $optName = $lastArgs[0]; 834 $width = $lastArgs[1]; 835 836 $selectPage = $this->getConf('selectPage'); 837 838 $found = 0; 839 $selectPath = "data/pages"; 840 $selectSplit = explode(':', $selectPage); 841 foreach ($selectSplit as $split) { 842 $selectPath .= "/" . $split; 843 } 844 $selectPath .= ".txt"; 845 846 if (file_exists($selectPath)){ 847 $fileLines = file($selectPath); 848 foreach ($fileLines as $fileLine) { 849 $lineElements = explode(' ', $fileLine); 850 // Is the defined name equal to name in argument list? 851 if ($lineElements[0] == $optName) { 852 $options = explode(",", substr($fileLine, strlen($lineElements[0])+1)); 853 $found = 1; 854 } 855 } 856 } 857 // Named SelectBox not found in WikiPage 858 if($found == 0) { 859 $data .= $this->insertError($optName, 2); 860 break; 861 } 862 } else { // arguments where not correct 863 $data .= $this->insertError($name, 1); 864 break; 865 } 866 867 // routine to check if names are unique 868 if (in_array($name, $nameArray)) { 869 $data .= $this->insertError($name, 0); 870 break; 871 } 872 array_push($nameArray, $name); 873 874 if (is_file($this->mailPath.'mail.tmp')) { 875 $mail .= " . \"\\n $name ==> \" . \$_POST['$name'] " . "\n"; 876 } 877 878 $data .= $this->createSelectBox($name, $text, $width, $options, $value); 879 break; 880 881 case 'Checkbox' : 882 // number of arguments given is correct? 883 if (count($explQuoteMark) != 3 884 || count(explode(' ', trim($explQuoteMark[0]))) != 2 885 || count(explode(' ', trim($lastArgs))) != 1 ) { 886 $data .= $this->insertError($name, 1); 887 break; 888 } 889 // routine to check if names are unique 890 if (in_array($name, $nameArray)) { 891 $data .= $this->insertError($name, 0); 892 break; 893 } 894 array_push($nameArray, $name); 895 896 // should checkbox be checked 897 // Not working proberly if Standard=checked but not checked when sending 898 // In this case the value is not set and therefore it is checked again when coming back 899 $checked = ''; 900 if (isset($value)) { 901 if ($value='on') $checked = 'CHECKED'; 902 } else { 903 if ($lastArgs[0] == "1") $checked = 'CHECKED'; 904 } 905 906 if (is_file($this->mailPath.'mail.tmp')) { 907 $mail .= " . \"\\n $name ==> \" . \$_POST['$name'] " . "\n"; 908 } 909 910 $data .= '<tr><td colspan="2">' 911 .'<input type="checkbox" ' 912 .'name="'.$name.'" ' 913 .$checked 914 .' value="'.$text.'"/> ' 915 .$this->parsed($text) 916 .'</td></tr>'; 917 break; 918 919 case 'Textarea' : 920 // number of arguments given is correct? 921 if (count($explQuoteMark) != 3 922 || ( count($lastArgs) != 1 923 && count($lastArgs) != 2 )) { 924 $data .= $this->insertError($name, 1); 925 break; 926 } 927 928 // routine to check if names are unique 929 if (in_array($name, $nameArray)) { 930 $data .= $this->insertError($name, 0); 931 break; 932 } 933 array_push($nameArray, $name); 934 935 if (is_file($this->mailPath.'mail.tmp')) { 936 $mail .= " . \"\\n $name ==> \\\" \" . \$_POST['$name'] . \" \\\" \" " . "\n"; 937 } 938 939 $rows = $lastArgs[0]; 940 $width = $lastArgs[1]; 941 $data .= $this->createTextarea($name, $text, $value, $rows, $width); 942 break; 943 944 case 'Submit' : 945 // number of arguments given is correct? 946 if ( count($lastArgs) != 1 947 || count($explQuoteMark) != 3) { 948 $data .= $this->insertError($explQuoteMark[1], 1); 949 break; 950 } 951 952 $data .= '<tr><td></td><td>' 953 .'<input class="button" type="submit" name="submit" ' 954 .'value="'.$explQuoteMark[1] 955 .'" style="width:'.$lastArgs[0].'px;" />' 956 .'</td></tr>'; 957 break; 958 959 case 'Static' : 960 switch (count($explQuoteMark)) { 961 case 3 : 962 $data .= "<tr><td colspan=\"2\">" 963 .$this->parsed($explQuoteMark[1]) 964 ."</td></tr>"; 965 break; 966 case 5 : 967 $data .= "<tr><td>" 968 .$this->parsed($explQuoteMark[1]) 969 ."</td><td>" 970 .$this->parsed($explQuoteMark[3]) 971 ."</td></tr>"; 972 break; 973 default : 974 $data .= $this->insertError($explQuoteMark[0], 1); 975 } 976 break; 977 978 case 'Radio' : 979 // number of arguments given is correct? 980 if (count($explQuoteMark) != 5 981 || count(explode(' ', trim($explQuoteMark[0]))) != 2 982 || count($lastArgs) > 1 983 || $lastArgs[0] != '') { 984 $data .= $this->insertError($name, 1); 985 break; 986 } 987 // routine to check if names are unique 988 if (in_array($name, $nameArray)) { 989 $data .= $this->insertError($name, 0); 990 break; 991 } 992 array_push($nameArray, $name); 993 994 $options = explode(',', $explQuoteMark[3]); 995 $data .= $this->createRadioButton($name, $text, $options, $value); 996 997 if (is_file($this->mailPath . 'mail.tmp')) { 998 $mail .= " . \"\\n $name ==> \" . \$_POST['$name'] " . "\n"; 999 } 1000 break; 1001 1002 case 'File' : 1003 // number of arguments given is correct? 1004 if (count($explQuoteMark) != 3 1005 || count($explBlank) < 2 1006 || count($lastArgs) < 1 1007 || $lastArgs[0] == '') { 1008 $data .= $this->insertError($name, 1); 1009 break; 1010 } 1011 1012 $maxsize = $lastArgs[0]; 1013 $width = $lastArgs[1]; 1014 $data .= $this->createFileElement($text, $width, $value); 1015 $data .= $this->createHidden('file_maxsize', $maxsize); 1016 break; 1017 1018 case 'Line' : 1019 $data .= '<tr><td colspan="2"> </td></tr>'; 1020 break; 1021 1022 case 'Buttons' : 1023 // number of arguments given is correct? 1024 if (count($explQuoteMark) != 5 1025 || count($lastArgs) != 1 1026 || trim($explQuoteMark[2]) != '') { 1027 $data .= $this->insertError('Buttons', 1); //TODO: localize string 1028 break; 1029 } 1030 1031 $data .= '<tr><td></td><td> ' 1032 .'<input class="button" type="submit" ' 1033 .'value="' . $explQuoteMark[1] 1034 .'" style="width:'.$lastArgs[0].'px;" />' 1035 .'<input class="button" type="reset" ' 1036 .'value="'.$explQuoteMark[3] 1037 .'" style="width:'.$lastArgs[0].'px;" /> ' 1038 .'</td></tr>'; 1039 break; 1040 1041 case 'Constraint' : 1042 // number of arguments given is correct? 1043 if (count($explQuoteMark) < 3 1044 || count(explode(' ', trim($explQuoteMark[0]))) != 2) { 1045 $data .= $this->insertError('Constraint ' . $name, 1); 1046 break; 1047 } 1048 $error = $explQuoteMark[1]; 1049 $constraint .= $this->createConstraints($line, $name, $error); 1050 break; 1051 1052 case '': 1053 break; 1054 1055 // keyword was not recognised 1056 default: 1057 $data .= '<tr><td colspan="2"><span style="color:#FF0000;">' 1058 .$this->getLang('wrong_kw').' ' . trim($explBlank[0]) . '!' 1059 .'</span></td></tr>'; 1060 break; 1061 } //switch body 1062 } //foreach line 1063 1064 // File for creating Mail Script 1065 if ($mail != '') { 1066 if (isset($constraint) && $constraint != '') { 1067 $this->writebefore($this->mailPath.'mail.tmp', $constraint); 1068 } 1069 // file_put_contents($mailFilePath . 'mail.tmp', $mail, FILE_APPEND) or die("Could not write to mailscript temp file: $php_errormsg"); 1070 $f = fopen($this->mailPath.'mail.tmp','a') or die($this->getLocalLang('cannot_open')); 1071 fwrite($f, $mail); 1072 fclose($f); 1073 } else { 1074 if (isset($constraint) && $constraint != '' && $this->internalScript) { 1075 $this->writebefore($this->mailPath.'constraint.tmp', $constraint); 1076 } 1077 } 1078 } //switch $state 1079 1080 // return created string 1081 return $data; 1082 } 1083 1084 /** 1085 * Create output 1086 */ 1087 function render($mode, &$renderer, $data) { 1088 if ($mode == 'xhtml') { 1089 $renderer->info['cache'] = false; 1090 $renderer->doc .= $data; 1091 return true; 1092 } 1093 return false; 1094 } 1095} 1096