tags, and HTML files have their body * content extracted and displayed inside a
. * Other file types can be added (see below). * * (:includeupload myfile.txt:) * * (:includeupload myfile2.html:) * * This can also include files attached to other groups, in the same way * that Attach: can. For example: * * (:includeupload SomeGroup./thatfile.html:) * * Attached files will only be displayed if the user is authorized * to read them (that is, is authorized to read the page/group * they are associated with). This introduces a new authorization * level called 'includeupload', which defaults to the same as 'read'. * * To include a file which resides under the DOCUMENT_ROOT of the webserver, * give the path relative to the DOCUMENT_ROOT of the webserver. The path * must start with '/' to distinguish it from attached files. * * (:includeupload /path/relative/to/web/root/file.txt:) * * So, for example, if the file's URL would normally be * http://www.example.com/foo/bar.txt * then the directive would be * (:includeupload /foo/bar.txt:) * * By default, this uses URL fopen to open such files, so as to * comply with the webserver's security. However, url_fopen is not * always enabled in PHP installations. If this is the case, then * you need to set * $IncludeUploadUrlFopenEnabled = 0; * in your local/config.php file. * When $IncludeUploadUrlFopenEnabled is false, then this will * attempt to read the file directly from the filesystem, bypassing * the webserver. * * A text-to-HTML converter can be called for text files, by setting * $IncludeUploadToHtmlCmd['txt'] to a suitable command. For example * * $IncludeUploadToHtmlCmd['txt'] = '/usr/bin/txt2html --xhtml'; * * This command will be passed a filename, and the output is expected to * be given on standard output. The output of this command will have the * body content extracted as with a HTML file. * * This mechanism can be used, in addition, to display files of different * types, so long as you have a command that will convert that file * to HTML in standard output. The type is determined either by the * filename extension, or overridden by the type= argument. * * This can also be used to give different arguments to the text * conversion command, by defining a different "type" and setting * the type of that file with the type= argument. * For example, supposing I have a poem in mypoem.txt * Make a special 'poem' type, with different arguments: * * $IncludeUploadToHtmlCmd['poem'] = '/usr/bin/txt2html --xhtml --short_line_length=80'; * * Then give it the poem type: * * (:includeupload type=poem mypoem.txt:) * * Additional options: * - class: the CSS class to give the enclosing container. The default * class is 'includeup'. * * (:includeupload class=foo bar.html:) * * To activate this script, copy it into the cookbook/ directory, then add * the following line to your local/config.php: * * include_once("$FarmD/cookbook/includeupload.php"); * * Version 2019-01-26 (Siegfried Seibert) * update for PHP 7.2 compatibility * */ $RecipeInfo['IncludeUpload']['Version'] = '20190126'; global $IncludeUploadTextToHtmlCmd; SDV($IncludeUploadTextToHtmlCmd, ''); global $IncludeUploadUrlFopenEnabled; SDV($IncludeUploadUrlFopenEnabled, 1); global $IncludeUploadToHtmlCmd; SDVA($IncludeUploadToHtmlCmd, array( 'txt' => $IncludeUploadTextToHtmlCmd, )); global $HandleAuth; SDV($HandleAuth['includeupload'], 'read'); # Create markup that allows including files directly into wiki pages if($GLOBALS['VersionNum'] < 2002056) { # we want the cookbook to also work with older PmWiki versions Markup('includeupload', 'inline', '/\\(:includeupload(\\s+.*?):\\)/ei', "IncludeUploadIncludeFile(\$pagename, '$1 ')"); } else { Markup("includeupload", "inline", "/\\(:includeupload(\\s+.*?):\\)/i", "MarkupIncludeUploadIncludeFile"); } function MarkupIncludeUploadIncludeFile($m) { extract($GLOBALS["MarkupToHTML"]); # get $pagename return IncludeUploadIncludeFile($pagename, $m[1]); } global $IncludeUploadObject; $IncludeUploadObject = new IncludeUpload1; function IncludeUploadIncludeFile($pagename, $argstr) { global $IncludeUploadObject; return $IncludeUploadObject->include_file($pagename, $argstr); } class IncludeUpload1 { var $class; function IncludeUpload() { $this->class = 'includeup'; } function include_file($pagename, $argstr) { global $UploadFileFmt, $UploadUrlFmt, $UploadPrefixFmt; global $IncludeUploadTextToHtmlCmd; global $IncludeUploadToHtmlCmd; global $UrlScheme, $IncludeUploadUrlFopenEnabled; global $HandleAuth, $AuthFunction; $args = ParseArgs($argstr); $path = ($args[''] ? implode('', $args['']) : ''); $class = ($args['class'] ? $args['class'] : $this->class); $abs_url = ''; # figure out the file path if (preg_match("/^\s*\//", $path)) { # a path was given, give it a http: path # so that this will honour Apache permissions # However, this will only work if allow_url_fopen is enabled. if ($IncludeUploadUrlFopenEnabled) { $http = ($UrlScheme ? $UrlScheme : 'http'); $filepath = $http . '://' . $_SERVER['HTTP_HOST'] . $path; } else { $filepath = $_SERVER['DOCUMENT_ROOT'] . $path; } // make the abs_url from the part of the URL minus the file $bits = explode("/", $filepath); array_pop($bits); $abs_url = implode('/', $bits); $abs_url .= '/'; } else { if (preg_match('!^(.*)/([^/]+)$!', $path, $match)) { $pagename = MakePageName($pagename, $match[1]); $path = $match[2]; } // permission check for accessing files from given page if (!$AuthFunction($pagename, $HandleAuth['includeupload'], false)) { return Keep("(:includeupload $path:) failed: access denied to include files from $pagename
\n"); } $upname = MakeUploadName($pagename, $path); $filepath = FmtPageName("$UploadFileFmt/$upname", $pagename); $abs_url = PUE(FmtPageName("$UploadUrlFmt$UploadPrefixFmt", $pagename)); } // read the file; if there was failure, the content is empty $filetext = $this->read_file($filepath); if ($filetext) { $ext = ''; if (preg_match('!\.(\w+)$!', $filepath, $match)) { $ext = $match[1]; } $filetype = ($args['type'] ? $args['type'] : $ext); if ($IncludeUploadToHtmlCmd[$filetype]) { $command = $IncludeUploadToHtmlCmd[$filetype]; $tempfile = $this->put_file($filetext); $fcont = `$command $tempfile`; $fcont = $this->extract_body($fcont); $fcont = $this->absolute_url($fcont, $abs_url); @unlink($tempfile); return Keep(($class ? "
" : '
') . $fcont . '
'); } else if (preg_match('/htm.?/', $ext)) { $fcont = $this->extract_body($filetext); $fcont = $this->absolute_url($fcont, $abs_url); return Keep(($class ? "
" : '
') . $fcont . '
'); } else { // by default, treat as text and escape HTML chars return Keep(($class ? "
" : '
')
           /*	    . "filetype=$filetype\n"  */
                . htmlspecialchars($filetext) . '
'); } } # fall through return Keep("(:includeupload $path:) failed: Could not open $filepath
\n"); } // include_file // get the contents of the file function read_file($filepath) { global $WorkDir; if ($filepath == "") return ''; $fp = @fopen($filepath, "r"); if (!$fp) return ''; $text = ''; while (!feof($fp)) { $text .= fread($fp,4096); } fclose($fp); return $text; } // put the given text into a temporary file; // return the name of the temporary file. function put_file($text) { $tempfile = tempnam($WorkDir, "incup"); $tfp=@fopen($tempfile, 'w'); if (!$tfp) return ''; fputs($tfp, $text); fclose($tfp); return $tempfile; } // extract the body from the file function extract_body ($html) { $body = $html; $body = str_replace("", '', $body); $body = str_replace("", '', $body); $offset = strpos($body, ""); $offset = $offset + 1; $body = substr($body, $offset); return $body; } // extract_body // convert relative to absolute URLs // (Function from: http://www.howtoforge.com/forums/showthread.php?t=4) function absolute_url($txt, $base_url){ // if there's no URL given, do nothing. if (!$base_url) { return $txt; } $needles = array('href="', 'src="', 'background="'); $new_txt = ''; if(substr($base_url,-1) != '/') $base_url .= '/'; $new_base_url = $base_url; $base_url_parts = parse_url($base_url); foreach($needles as $needle){ while($pos = strpos($txt, $needle)) { $pos += strlen($needle); if (substr($txt,$pos,7) != 'http://' && substr($txt,$pos,8) != 'https://' && substr($txt,$pos,6) != 'ftp://' && substr($txt,$pos,5) != 'news:' && substr($txt,$pos,7) != 'telnet:' && substr($txt,$pos,7) != 'mailto:' && substr($txt,$pos,1) != '#') { if (substr($txt,$pos,1) == '/') { $new_base_url = $base_url_parts['scheme'].'://'.$base_url_parts['host']; } $new_txt .= substr($txt,0,$pos).$new_base_url; } else { $new_txt .= substr($txt,0,$pos); } $txt = substr($txt,$pos); } $txt = $new_txt.$txt; $new_txt = ''; } return $txt; } } /* class IncludeUpload */