* @license http://www.gnu.org/licenses/gpl.html GNU General Public License * @version 1.4beta1 * * new in 1.1: added $JJSCMSPrivateSection and $JJSCMSPublicSection to global statement in jjsCmsObCallback * new in 1.2: compare cache mtime and page time, only write cache file if page is newer * new in 1.3: remove session_name parameter from urls in cached version, url rewriting bugfixes * new in 1.4beta1: major refactoring * - action jjscmspublish * - use jjsEditRev/jjsApprovePageRev PageAttributes if available * - use passwd auth with level "jjscmspublish" * - prefix JJSCMS for all global identifiers. * for example $PublishDir is now $JJSCMSPublishDir * - renamed * $PublishPublicSection to $JJSCMSPublicSection * $PublishPrivateSection to $JJSCMSPrivateSection * $PicsUrl to $JJSCMSAttachUrl * - helpful(?) error messages appended as html-comment * - use global $JJSCMSPublishROSPatterns for all replacement patterns * - rewriting is only done, if the $JJSCMS... variable is not empty * - new configuration variable JJSCMSAction * new in 1.4beta2: * - fix unwanted slash-removal in url rewriting */ define(JJSCMS, '1.4beta2'); ## Configuration Variables /** * $JJSCMSPublishDir: Directory where the static (public) version of the pages will be written to */ SDV($JJSCMSPublishDir, '../../pmwiki/published'); /** * $JJSCMSPublishUrl: URL prefix to be used in all local links in public version of the page. * Should either point to place where the server is serving $JJSCMSPublishDir, or to a * skript that takes ..html as parameter */ SDV($JJSCMSPublishUrl, 'index.php?showcmspage='); /** * $JJSCMSAttachUrl */ SDV($JJSCMSAttachUrl,'pmwiki/pics/'); /** * $JJSCMSPublishAttachUrl: Point to pmwikis shared upload dir */ SDV($JJSCMSPublishAttachUrl,'pmwiki/pics/'); /** * $JJSCMSPublishPubDirUrl: Point to pmwikis shared pub dir */ SDV($JJSCMSPublishPubDirUrl, 'pmwiki/pub/'); /** * Anything enclosed by * in your template will only show up in the private (editable) version of the page. */ SDV($JJSCMSPrivateSection, 'dontpublish'); /** * Anything enclosed by * in your template will only show up in the public (static) version of the page. */ SDV($JJSCMSPublicSection, 'dontedit'); ## ## SDV($jjsUseTemplate, false); /** * parameter jjscmsaction selects which pmwiki action is captured * default for jjscmsaction is 'browse' */ SDV($JJSCMSAction, 'browse'); /** * JJSCMSObCallback * outpbut buffering callback function to be registered with php * does preg replacement using rules from $JJSCMSPublishROSPatterns * saves output to $JJSCMSPublishDir * removes $JJSCMSPublishPublicSection before showing the page */ function JJSCMSObCallback($buffer) { global $pagename, $PCache, $ScriptUrl, $PubDirUrl, $JJSCMSAttachUrl, $JJSCMSPublishUrl, $JJSCMSPublishAttachUrl, $JJSCMSPublishPubDirUrl, $JJSCMSPublishDir, $JJSCMSPrivateSection, $JJSCMSPublicSection, $JJSCMSPublishROSPatterns; $filename = $JJSCMSPublishDir . '/' . $pagename . '.html'; // setup some regex replacement patterns // // remove private sections if (!empty($JJSCMSPrivateSection)) { $JJSCMSPublishROSPatterns['/\<\!\-\- ' . $JJSCMSPrivateSection . ' \-\-\>.*\<\!\-\- \/' . $JJSCMSPrivateSection . ' \-\-\>/Us'] = '' ; } // remove trailing PHPSESSID $JJSCMSPublishROSPatterns['/([&\?])' . session_name() . '\=[A-Za-z0-9]+$/'] = '' ; // remove PHPSESSID from start or in the middle of the parameter list $JJSCMSPublishROSPatterns['/([&\?])' . session_name() . '\=[A-Za-z0-9]+&?/'] = '\1' ; // rewrite page links $JJSCMSPublishROSPatterns['/([\'"])' . str_replace('/','\/',$ScriptUrl) . '\?n\=([^#&]+)(#|&[^\1]+)?\1/Us'] = '\1' . $JJSCMSPublishUrl . '\2.html\3\1' ; // rewrite picture/attachment links if (!empty($JJSCMSAttachUrl) && !empty($JJSCMSPublishAttachUrl)) { $JJSCMSPublishROSPatterns['/([\'"])' . str_replace('/','\/', $JJSCMSAttachUrl) . '\/([^\1]+)\1/Us'] = '\1' . $JJSCMSPublishAttachUrl . '/\2\1' ; } // rewrite pub links if (!empty($PubDirUrl) && !empty($JJSCMSPublishPubDirUrl)) { $JJSCMSPublishROSPatterns['/([\'"])' . str_replace('/','\/', $PubDirUrl) . '\/([^\1]+)\1/Us'] = '\1' . $JJSCMSPublishPubDirUrl . '/\2\1' ; } // apply $JJSCMSPublishROSPatterns before saving // $error = ''; $x = $buffer; foreach ($JJSCMSPublishROSPatterns as $pattern => $replace) { $lastgood = $x; $x = preg_replace($pattern, $replace, $x); if (NULL == $x || '' == $x) { $error .= "\n\n" . 'no output from JJSCMSPublishROSPatterns[\'' . $pattern . '\'] = ' . $replace; $x = $lastgood; } else { ###$error .= "\n\n" . $lastgood ; } } $fh = fopen($filename,'w'); if (!$fh) { $error .= "\n" . 'JJSCMS failed opening output file. "' . $filename . '"'; } else { $written = fwrite($fh, $x); if (!$written) { $error .= "\n" . 'JJSCMS failed writing to output file "' . $filename . '"'; } } fclose($fh); // remove public only sections $x = preg_replace( '/\<\!\-\- ' . $JJSCMSPublicSection . ' \-\-\>.*\<\!\-\- \/' . $JJSCMSPublicSection . ' \-\-\>/Us', '', $buffer); // append error msg if ('' != $error) { $x .= "\n" . ''; } return $x; } // JJSCMSObCallback /** *JJSCMSHandlePublish * install JJSCMSObCallback to capture all output from the "browse" action */ function JJSCMSHandlePublish($pagename, $auth='jjscmspublish') { global $HandleActions, $JJSCMSAction, $jjsSession, $jjsUseTemplate; /** if jjsapprovepage is used don't publish if not approved rev */ if (defined('JJSAPPROVEPAGE')) { $page = RetrieveAuthPage($pagename, $auth, true); if (!$page) { Abort("?unable to read $pagename"); } if (@$page['jjsApprovePageRev']) { if ('any' == $page['jjsApprovePageRev']) { $canpublish = true; } elseif (0 > intval($page['jjsApprovePageRev'])) { $canpublish = false; } elseif (defined('JJSEDITREV') && @$page['jjsEditRev']) { $canpublish = intval($page['jjsEditRev']) == intval($page['jjsApprovePageRev']); } } else { $canpublish = false; } } else { $canpublish = true; } if (!$canpublish) { if (isset($_REQUEST['jjsiterator'])) { // don't stop iteration $HandleActions[$JJSCMSAction]($pagename); return; } else { $errmsg = FmtPageName('revision mismatch - must approve page before publishing $Group.$Name $jjsEditRev != $jjsApprovePageRev ', $pagename); Abort($errmsg); } } ob_start('JJSCMSObCallback'); $HandleActions[$JJSCMSAction]($pagename); if ($jjsUseTemplate) { $jjsTemplateSrc = ob_get_contents(); ob_end_clean(); // post-post-process output $smarty = new c_template(); $smarty->setSrc($jjsTemplateSrc); if (isset($jjsSession)) { $smarty->assign_by_ref('session', $jjsSession); } $smarty->display('var:smarty_tpl_src'); #echo $jjsTemplateSrc; } else { ob_end_flush(); } } // JJSCMSHandlePublish $HandleActions['jjscmspublish'] = JJSCMSHandlePublish; $HandleAuth['jjscmspublish'] = 'jjscmspublish'; $PageAttributes['passwdjjscmspublish'] = '$[set new publish password]'; $DefaultPasswords['jjscmspublish'] = ''; $AuthCascade['jjscmspublish'] = 'edit';