/* config */
// 是否创建首页的静态文件
define('IS_INDEX',true);// false = do not create home page cache
/*end of config*/
define('COSVERSION','2.7.3'); // 定义插件版本
// 引入wp的文件操作函数,后面将用到其中的get_home_path
require_once(ABSPATH . 'wp-admin/includes/file.php');
/* end of config */
$sm_locale = get_locale(); // 获取语言环境方便后面的本地化处理
// 得到语言环境对应的本地化翻译文件,当然现在只有中文的cosbeta-zh_CN.mo
$sm_mofile = dirname(__FILE__) . "/cosbeta-$sm_locale.mo";
// 加载本地化的翻译(http://codex.wordpress.org/Function_Reference/load_textdomain)
load_textdomain('cosbeta', $sm_mofile);
// 得到博客网站的url (http://codex.wordpress.org/Option_Reference)
$cossithome = get_option('home');
// 获取调用链接的完整url
$script_uri = rtrim( "http://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"] ,"/");
$home_path = get_home_path(); // 得到wp所安装的绝对物理目录
define('SCRIPT_URI',$script_uri); // 定义调用链接
define('CosSiteHome',$cossithome); // 定义网站url
define('CosBlogPath', $home_path); // 定义网站安装物理位置
// 定义插件生效标记
define("COSMETA","<!--this is a real static html file created at ".date("Y-m-d H:i:s").
" by cos-html-cache ".COSVERSION." -->");
// 创建静态文件的函数
function CreateHtmlFile($FilePath,$Content){
// 去掉文件名中的一些非法符号
$FilePath = preg_replace('/[ <>\'\"\r\n\t\(\)]/', '', $FilePath);
// if there is http:// $FilePath will return its bas path
// 分隔文件路径,比如/home/xxx/xxx/xxx/xxx.html,
// 如果是类似http://xxx.com/html/y2012/xxx.html,将传入/html/y2012/xxx.html
// (http://cn2.php.net/manual/zh/function.explode.php)
$dir_array = explode("/",$FilePath);
//split the FilePath
$max_index = count($dir_array) ;
$i = 0;
$path = $_SERVER['DOCUMENT_ROOT']."/"; // 获取网站的根目录,比如/home/username/
while( $i < $max_index ){
$path .= "/".$dir_array[$i]; // 把子目录一级一级加到路径上
$path = str_replace("//","/",$path); // 如果有//则替换成/
if( $dir_array[$i] == "" ){ // 如果这目录值为空则跳过去,这个判断放在循环的最前面可能更合适
$i ++ ;
continue;
}
// 上面的代码似乎可以写得更精练
if( substr_count($path, '&') ) return true; // 如果路径中有&符号,这不好处理,不管了
if( substr_count($path, '?') ) return true; // 有?也不管了
if( !substr_count($path, '.htm') ){ // 如果不包含.htm,原来传了个路径进来
//if is a directory
// 如果路径不存在,贱之,并赋读写运行权,如果存在,那八成也是这里贱的
if( !file_exists( $path ) ){
@mkdir( $path, 0777);
@chmod( $path, 0777 );
}
}
$i ++; // 这个搞完,继续
}
if( is_dir( $path ) ){ // 如果上面折腾完后,发现是个目录,那就是说要创建index.html
$path = $path."/index.html";
}
// 如果html页面没创建完整,那还是不管算了
if ( !strstr( strtolower($Content), '</html>' ) ) return;
//if sql error ignore...
$fp = @fopen( $path , "w+" ); // 好了开始写了,文件在就准备覆盖内容,不在就贱之
if( $fp ){ // 说明有权限写
@chmod($path, 0666 ) ; // 给文件先赋个权限
@flock($fp ,LOCK_EX ); // 锁定
// write the file。
fwrite( $fp , $Content );// 写静态文件内容
@flock($fp, LOCK_UN); // 解锁
fclose($fp); // 完事
}
}
/* read the content from output buffer */
// 在用户登录后,才会有动静,先初始化为不管,这是个非常好的习惯,
// 为了安全,一般的看不懂的东西还是躲开算了
$is_buffer = false;
// 如果调用的是/year/y2012/xxx.html或访问的url就是网站url
if( substr_count($_SERVER['REQUEST_URI'], '.htm') || ( SCRIPT_URI == CosSiteHome) ){
if( strlen( $_COOKIE['wordpress_logged_in_'.COOKIEHASH] ) < 4 ){ // 用户登录了,估计得干活了
$is_buffer = true;
}
if( substr_count($_SERVER['REQUEST_URI'], '?')) $is_buffer = false; // 参数调用,躲
if( substr_count($_SERVER['REQUEST_URI'], '../')) $is_buffer = false; // 太危险了,还是躲开好了
}
if( $is_buffer ){ // 真得得干活了
ob_start('cos_cache_ob_callback'); // 开干
register_shutdown_function('cos_cache_shutdown_callback'); // 高潮并结束,很快的
}
function cos_cache_ob_callback($buffer){ // 这里就是就会从wp的输出缓冲拿内容准备写到静态文件中
// 下面一堆正则表达式,不是给一般人看的,我是一般人,所以不看了
// 不过显然是在处理评论相关的信息
$buffer = preg_replace('/(<\s*input[^>]+?(name=["\']author[\'"])[^>]+?value=(["\']))([^"\']+?)\3/i', '\1\3', $buffer);
$buffer = preg_replace('/(<\s*input[^>]+?value=)([\'"])[^\'"]+\2([^>]+?name=[\'"]author[\'"])/i', '\1""\3', $buffer);
$buffer = preg_replace('/(<\s*input[^>]+?(name=["\']url[\'"])[^>]+?value=(["\']))([^"\']+?)\3/i', '\1\3', $buffer);
$buffer = preg_replace('/(<\s*input[^>]+?value=)([\'"])[^\'"]+\2([^>]+?name=[\'"]url[\'"])/i', '\1""\3', $buffer);
$buffer = preg_replace('/(<\s*input[^>]+?(name=["\']email[\'"])[^>]+?value=(["\']))([^"\']+?)\3/i', '\1\3', $buffer);
$buffer = preg_replace('/(<\s*input[^>]+?value=)([\'"])[^\'"]+\2([^>]+?name=[\'"]email[\'"])/i', '\1""\3', $buffer);
// 不是一般人看的东西结束
// 内容里没有插件做的标记,不能管
if( !substr_count($buffer, '<!--cos-html-cache-safe-tag-->') ) return $buffer;
// 有密码保护的文章不能管
if( substr_count($buffer, 'post_password') > 0 ) return $buffer;//to check if post password protected
$wppasscookie = "wp-postpass_".COOKIEHASH;
// 还是不能管
if( strlen( $_COOKIE[$wppasscookie] ) > 0 ) return $buffer;//to check if post password protected
/* 这些内容还是放在common.js.php里的,用js去处理吧
$comment_author_url='';
$comment_author_email='';
$comment_author='';*/
elseif( SCRIPT_URI == CosSiteHome) {// creat homepage // 噢,首页,这个得管
$fp = @fopen( CosBlogPath."index.bak" , "w+" ); // 先把内容弄进index.bak里
if( $fp ){
@flock($fp ,LOCK_EX );
// write the file。
fwrite( $fp , $buffer.COSMETA ); // 写,后面再加点标记说明静态文件创建成功
@flock($fp, LOCK_UN);
fclose($fp);
}
if(IS_INDEX) // 如果真得要创建首页静态文件, 就把index.bak改成index.html
@rename(CosBlogPath."index.bak",CosBlogPath."index.html");
}
else // 其它情况,试着创建静态文件,并在后面加个标记
CreateHtmlFile($_SERVER['REQUEST_URI'],$buffer.COSMETA );
return $buffer;
}
function cos_cache_shutdown_callback(){ // 把静态文件真得写到物理硬盘上去,高潮过程总是很短
ob_end_flush();
flush();
}
if( !function_exists('DelCacheByUrl') ){
function DelCacheByUrl($url) { // 通过url来删静态文件
$url = CosBlogPath.str_replace( CosSiteHome,"",$url ); // 如果是完整url,就把网站给去掉
$url = str_replace("//","/", $url ); // 把所有//替换成/
if( file_exists( $url )){ // 文件存在
// 如果是目录就先删里面的index.html,再删目录
if( is_dir( $url )) {@unlink( $url."/index.html" );@rmdir($url);}
else @unlink( $url ); // 否则直接删静态文件
}
}
}
if( !function_exists('htmlCacheDel') ){
// create single html
function htmlCacheDel($post_ID) { // 通过文章id来删静态文件
if( $post_ID == "" ) return true;
$uri = get_permalink($post_ID);
DelCacheByUrl($uri );
}
}
if( !function_exists('htmlCacheDelNb') ){
// delete nabour posts
// 如果把文章删了,那也得把邻居两文章的静态文章同时删除,避免上一篇下一篇出问题
// 不过你看出来了么,对于文章id 大于被删文章的sql语句有点小问题,新版将会解决(2.7.4版中已解决)
function htmlCacheDelNb($post_ID) {
if( $post_ID == "" ) return true;
$uri = get_permalink($post_ID);
DelCacheByUrl($uri );
global $wpdb;
$postRes=$wpdb->get_results("SELECT `ID` FROM `" . $wpdb->posts . "` WHERE post_status = 'publish' AND post_type='post' AND ID < ".$post_ID." ORDER BY ID DESC LIMIT 0,1;");
$uri1 = get_permalink($postRes[0]->ID);
DelCacheByUrl($uri1 );
$postRes=$wpdb->get_results("SELECT `ID` FROM `" . $wpdb->posts . "` WHERE post_status = 'publish' AND post_type='post' AND ID > ".$post_ID." ORDER BY ID DESC LIMIT 0,1;");
if( $postRes[0]->ID != '' ){
$uri2 = get_permalink($postRes[0]->ID);
DelCacheByUrl($uri2 );
}
}
}
//create index.html
if( !function_exists('createIndexHTML') ){
// 用户编辑、删除、新建了文章,首页就会有变动了,
// 所以得把首页静态文件先改个名,免得还是直接访问静态文件,看不到效果
function createIndexHTML($post_ID){
if( $post_ID == "" ) return true;
//[menghao]@rename(ABSPATH."index.html",ABSPATH."index.bak");
@rename(CosBlogPath."index.html",CosBlogPath."index.bak");//[menghao]
}
}
if(!function_exists("htmlCacheDel_reg_admin")) { // 把删除静态文件功能加到wp的管理菜单中
/**
* Add the options page in the admin menu
*/
function htmlCacheDel_reg_admin() {
if (function_exists('add_options_page')) {
add_options_page('html-cache-creator', 'CosHtmlCache',8, basename(__FILE__), 'cosHtmlOption');
//add_options_page($page_title, $menu_title, $access_level, $file).
}
}
}
add_action('admin_menu', 'htmlCacheDel_reg_admin');
if(!function_exists("cosHtmlOption")) { // 这就是wp里cos-html-cache选项功能
function cosHtmlOption(){
do_cos_html_cache_action();
?>
<div class="wrap" style="padding:10px 0 0 10px;text-align:left">
<form method="post" action="<?php echo $_SERVER["REQUEST_URI"]; ?>">
<p>
<?php _e("Click the button bellow to delete all the html cache files","cosbeta");?></p>
<p><?php _e("Note:this will Not delete data from your databases","cosbeta");?></p>
<p><?php _e("If you want to rebuild all cache files, you should delete them first,and then the cache files will be built when post or page first visited","cosbeta");?></p>
<p><b><?php _e("specify a post ID or Title to to delete the related cache file","cosbeta");?></b> <input type="text" id="cache_id" name="cache_id" value="" /> <?php _e("Leave blank if you want to delete all caches","cosbeta");?></p>
<p><input type="submit" value="<?php _e("Delete Html Cache files","cosbeta");?>" id="htmlCacheDelbt" name="htmlCacheDelbt" onClick="return checkcacheinput(); " />
</form>
</div>
<SCRIPT LANGUAGE="JavaScript">
<!--
function checkcacheinput(){
document.getElementById('htmlCacheDelbt').value = 'Please Wait...';
return true;
}
//-->
</SCRIPT>
<?php
}
}
/*
end of get url
*/
// deal with rebuild or delete
function do_cos_html_cache_action(){ // 完成wp中cos-html-cache选项中删除静态文件的操作
if( !empty($_POST['htmlCacheDelbt']) ){
@rename(CosBlogPath."index.html",CosBlogPath."index.bak");
@chmod( CosBlogPath."index.bak", 0666 );
global $wpdb;
if( $_POST['cache_id'] * 1 > 0 ){
//delete cache by id
DelCacheByUrl(get_permalink($_POST['cache_id']));
$msg = __('the post cache was deleted successfully: ID=','cosbeta').$_POST['cache_id'];
}
else if( strlen($_POST['cache_id']) > 2 ){
$postRes=$wpdb->get_results("SELECT `ID` FROM `" . $wpdb->posts . "` WHERE post_title like '%".$_POST['cache_id']."%' LIMIT 0,1 ");
DelCacheByUrl( get_permalink( $postRes[0]->ID ) );
$msg = __('the post cache was deleted successfully: Title=','cosbeta').$_POST['cache_id'];
}
else{
$postRes=$wpdb->get_results("SELECT `ID` FROM `" . $wpdb->posts . "` WHERE post_status = 'publish' AND ( post_type='post' OR post_type='page' ) ORDER BY post_modified DESC ");
foreach($postRes as $post) {
DelCacheByUrl(get_permalink($post->ID));
}
$msg = __('HTML Caches were deleted successfully','cosbeta');
}
}
if($msg)
echo '<div class="updated"><strong><p>'.$msg.'</p></strong></div>';
}
$is_add_comment_is = true; // 下面是处理文章评论,增加了js来处理,相关js在common.js.php中
/*
* with ajax comments
*/
if ( !function_exists("cos_comments_js") ){
function cos_comments_js($postID){
global $is_add_comment_is;
if( $is_add_comment_is ){
$is_add_comment_is = false;
?>
<script language="JavaScript" type="text/javascript" src="<?php echo CosSiteHome;?>/wp-content/plugins/cos-html-cache/common.js.php?hash=<?php echo COOKIEHASH;?>"></script>
<script language="JavaScript" type="text/javascript">
//<![CDATA[
var hash = "<?php echo COOKIEHASH;?>";
var author_cookie = "comment_author_" + hash;
var email_cookie = "comment_author_email_" + hash;
var url_cookie = "comment_author_url_" + hash;
var adminmail = "<?php echo str_replace('@','{_}',get_option('admin_email'));?>";
var adminurl = "<?php echo get_option('siteurl') ;?>";
setCommForm();
//]]>
</script>
<?php
}
}
}
function CosSafeTag(){ // 增加安全标记
if ( is_single() || (is_home() && IS_INDEX) ) {
echo "<!--cos-html-cache-safe-tag-->";
}
}
function clearCommentHistory(){ //
global $comment_author_url,$comment_author_email,$comment_author;
$comment_author_url='';
$comment_author_email='';
$comment_author='';
}
//add_action('comments_array','clearCommentHistory');
add_action('get_footer', 'CosSafeTag'); // 让安全标记加在footer前
add_action('comment_form', 'cos_comments_js'); // 评论特殊处理一下
/* end of ajaxcomments*/
if(IS_INDEX) add_action('publish_post', 'createIndexHTML'); // 有新文章对首页处理一下
add_action('publish_post', 'htmlCacheDelNb'); // 有新文章对相关静态文件处理一下
if(IS_INDEX) add_action('delete_post', 'createIndexHTML'); // 删除了文章也对首页处理一下
add_action('delete_post', 'htmlCacheDelNb'); // 删除文件对相关静态文件处理一下
//if comments add
add_action('edit_post', 'htmlCacheDel'); // 文章及评论有变动都要更新静态文件
if(IS_INDEX) add_action('edit_post', 'createIndexHTML'); // 可能影响首页,反正也更新一下吧
|