This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Description: This file is intended to be used as a "cookbook" extension to pmwiki 2, and is used to provided upload and display of CSV table data directly on a PmWiki page. Usage: Put the following line in your local/config.php file include_once("cookbook/CSVInclude.php"); Inline Wiki mark-up can be used in the table too. Block mark-up like bullets, indentation and heders will not work. The limitations are due to rendering the table using the simple table format. There is some special mark-up you can include in your source CSV table: * use <> to cause the cell to join with previous cell. This stands for del(ete) * use \\ in the text to denote a line break */ $RecipeInfo['CSVInclude']['Version'] = '2020-06-24'; ## This file is dependent on some variables and fuctions in the upload script. include_once("$FarmD/scripts/upload.php"); SDV($CSVIncludeLocalCachingEnabled, true); SDV($CSVIncludeLocalCacheFolder, 'uploads/csvincludecache/'); SDV($CSVIncludeDefaultCacheExpiration, 300); SDV($CSVIncludeFollowRedirects, true); # If the user has edit permissions to the current page, and has triggered cache # invalidation via the csv_include_invalidate_caches GET parameter, delete all cached # files associated with attachcsv directives on the current page. if ($_GET['csvinclude_clear_cache'] == 1) { $page = RetrieveAuthPage($pagename, 'read', false, READPAGE_CURRENT); if ($page['=auth']['edit']) { global $CSVIncludeLocalCacheFolder; preg_match_all("/\\[:attachcsv\\s+([^']+?)('[^']*')?(\\s+?expire=\\d+)?:\\]/", $page['text'], $matches); foreach ($matches[1] as $upname) { if (preg_match("/^https?:/",$upname)) { $url_hash = md5($upname); $filepath = $CSVIncludeLocalCacheFolder.$url_hash.'.csv'; @unlink($filepath); } } } Redirect($pagename); } ## [:attachcsv:] Markup('attachcsv','>if',"/\\[:(attachcsv\\s+.+?):\\]/", "AttachCSVDirectiveParse"); function AttachCSVDirectiveParse($m) { global $pagename; return PRR().AttachCSV($pagename,$m[1]); } /* Function: AttachCSV Description: takes a specification for a CSV file from the wiki mark-up and generates wiki mark-up from the file and includes it into the wiki mark-up steam. This allows the inclusion of wiki mark up in the CSV file itself. CSV files are drawn from the upload directery consitant with the group the file is referenced from. If a file is specifed that does not exist, an "[[Attach:]] is generated for the file to allow the upload of the file. Once the file exists, the CSV content is converted and included in the body of the wiki page. Mark-up syntax: [:attachcsv(''):] Mark-up examples: [:attachcsv bob.csv:] [:attachcsv boby sue.csv:] [:attachcsv billy bob.csv'border=1 width=100%':] */ function AttachCSV($pagename, $csvspec) { global $AttachCSVBadAnchorFmt, $Newline, $UploadFileFmt, $FmtV; SDV($AttachCSVBadAnchorFmt, "\$LinkText ⇑"); # Parse the the mark-up for file name and attributes if(preg_match("/^attachcsv\\s+([^']+)('([^']*)')?(\\s+?expire=(\\d+))?$/", $csvspec, $match)) { $upname = preg_replace("/&/", "&", rtrim($match[1])); # deal with empty attribute list $tableAttributes = isset($match[3]) ? $match[3] : ""; # Check if it's a URL. if (preg_match("/^https?:/",$upname)) { global $CSVIncludeLocalCachingEnabled; # If local caching is enabled, then we check to see if we have the remote CSV # cached locally; if not, or if the locally cached version exists but needs # to be invalidated, then we retrieve the remote version and cache it. if ($CSVIncludeLocalCachingEnabled) { global $CSVIncludeLocalCacheFolder, $CSVIncludeDefaultCacheExpiration, $CSVIncludeFollowRedirects; # Create the cache directory, if it doesn't exist. if (!file_exists($CSVIncludeLocalCacheFolder)) mkdir($CSVIncludeLocalCacheFolder); # Hash the URL (we use it as the filename for the locally cached version). $url_hash = md5($upname); $filepath = $CSVIncludeLocalCacheFolder.$url_hash.'.csv'; # We check whether we need to retrieve the remote file (i.e., if we # don't already have it, or if we do have it but we need to invalidate # the cached version). $retrieve_remote_file = true; if (file_exists($filepath)) { # Get cached file's modification date and compare age to specified # cache expiration time. # If the expiration time is set to a non-positive value, that means # "always invalidate" (a.k.a. "don't cache"). # (Isn't this equivalent to setting $CSVIncludeLocalCachingEnabled to # false? No, because this way, a user can disable caching for a # *particular* [:attachcsv:] call.) global $Now; $max_age = isset($match[5]) ? $match[5] : $CSVIncludeDefaultCacheExpiration; $retrieve_remote_file = ($max_age <= 0 || ($Now - filemtime($filepath)) > $max_age); } # If the given URL's content isn't cached, or the locally cached version # needs to be invalidated, retrieve it. if ($retrieve_remote_file == true) { if ($CSVIncludeFollowRedirects) `curl -L -o $filepath $upname`; else `curl -o $filepath $upname`; } } else { # If local caching is not enabled, we simply retrieve the CSV from the # remote URL with every page load. $filepath = $upname; } } else { # create file reference consistent with upload feature $filepath = FmtPageName("$UploadFileFmt/$upname", $pagename); # if the CSV file does not exist, generate an Attach directive to all # the upload of the file if(!file_exists($filepath)) { return("[[Attach:".$upname."]]"); } } # Open the CSV file and prep for parsing each line $csvFile = fopen($filepath, "r"); $rowNum = 0; $text = "||".$tableAttributes."\n"; # loop through each row and column and generate wiki simple table mark-up while($data = fgetcsv($csvFile,10000)) { $cellNum=0; for($cellNum = 0; $cellNum < count($data); $cellNum++) { $cellContents = $data[$cellNum]; if($cellContents == "") { $cellContents = " "; } else if($cellContents == "<>") { $cellContents = ""; } else { ## turn "\\" into line break and ## escape sequences of "||..." $cellContents = preg_replace(array("/\\\\\\\\/","/(\\|\\|+)/"), array("\\\\\\\\\n","[=\\1=]"), $cellContents); } $text .= "||".$cellContents; } $text .= "||\n"; } $text .= "\n"; return $text; } # just return the raw mark-up if it can't be parsed return("[:".$csvspec.":]"); } ## Make sure the CSV mime type is set if(!isset($UploadExts['csv'])) { $UploadExts['csv'] = 'text/plain'; } if(!isset($UploadExtSize['csv'])) { $UploadExtSize['csv'] = isset($UploadMaxSize) ? $UploadMaxSize : 50000; } ?>