Warning: Redis::connect(): connect() failed: Connection refused in /var/www/admclub.com/wp-content/object-cache.php on line 418
插件 | _站长俱乐部站长俱乐部

标签存档: 插件

很NB的jquery图片裁剪插件

http://fengyuanchen.github.io/cropper/ & …

继续阅读 »

开发域名保护+CDN加速系统插件

前年已经做了一个域名保护/CDN加速系统,仅内部人员使用。现在想把这个平台做成插件,整合到一些常的面板或者常用的系统中去。方便用户使用。先在这里做个时间MARK。

继续阅读 »

停用WordPress自动将半角附号转换成全角小插件

WordPress为了保证在页面输出时不被一些特殊附号破坏,默认情况下,它会自动将那些它认为会影响WordPress布局的附号转换成对应的全角附号.虽然WP在转换之前做了一些判断,但还是有时候反而破坏了文章:比如连续两个减号,它会转换成–(也就是两个中文的减号- )等.

James朋友刚才又提出了这个问题.于是下狠心,把它解决了.就写了这个插件.名字随便取的.现在只是保留了以下几个附号:

继续阅读 »

Magento常用资源整理一

这次主要是整理一些常用插件,绝大部分是免费的.比如有最国内的常用支付方式,一些少见但有时候会需要的插件等.

以connect20.magentocommerce.com开头的是connect 2.0的key.有些网页打不开了.但是connect的地址经测试是可用的.

Mangento 免费团购模块
http://connect20.magentocommerce.com/community/ZizioGroupSale

1.Alipay Payment Gateway(支付宝接口)(免费)
官方下载地址:

http://www.magentocommerce.com/magento-connect/cosmocommerce/extension/2226/alipay-payment-gateway
官方key:magento-community/Cosmo_Community_AlipayPayment
http://connect20.magentocommerce.com/community/Cosmo_Community_AlipayPaymentGateway

继续阅读 »

WordPress+UCenter整合插件

在网上发现这个插件,用于Wordpress+UCenter1.6的整合.收藏,方便日后使用.

此插件可以同步WP和UC的登录,用户信息的更新,头像更新等.

下载它的源码后发现,这个插件需要修改WP内核,以同步WP的新用户到UCenter.代码如下:
插件官网:http://chenyundong.com/
插件在WP上的网址:http://wordpress.org/extend/plugins/ucenter-integration/

继续阅读 »

[原创]Joomla+Ucenter(discuz)整合同步登录的插件

支持Joomla 1.7/2.5,UCenter 1.6.
注:Joomla 2.5.4后,因为对原来核心组件模块锁定了,不能从后台替换核心模块/插件。此问题正在解决中。
解决方法:

使用phpMyAdmin打开表:,然后找到name的值为plg_authentication_joomla的插件,然后修改这条记录。把enabled和protected均设值为0。
实现功能:

1.当从Joomla登录时,如果UCenter用户存在,则使用UCenter上的用户信息校验密码.则否使用Joomla本地信息.同步更新,删除Joomla和UCenter用户.

2.可选只使用UCenter用户信息,而不理会Joomla本地用户信息.

3.可选同步登录,删除,更新用户时,是否先检查用户是否存在重得,如果重得,则不作同步.

4.组件后台提供用户复制功能.按UCenter官方手册建议,使用前最好先将Joomla用户复制到UCenter.并需要处理好用户重名的问题.如果你的Joomla是新的,没有任何用户,可以不复制用户.如果你的系统存在除UCenter和Joomla之外的其它应用,建议纳UC官方的建议.否则可能出现权限提供的问题.

具个例子,某用户A在Joomla中是管理员,而之前并没在UC中.且在您的系统合并后,用户A一直没有登录过,就是说这个用户A一直没有被同步到UC中,而后来用户B却跑到你的第三方应用,如DZ X2注册了与用户A同名用户.那么当这个假的用户A从X2登录后,也能同步登录到Joomla中,原来的用户A,就无法再正常登录了.按UC官方的建议,事先将用户复制到UC的话,就可以很好地解决这个安全问题.

我发现其它同类插件很少提及到这点.

5.安装即用,不修改Joomla原来代码.

继续阅读 »

正在写Joomla与UCenter整合的插件

正在写Joomla与UCenter整合的插件,目前使用Joomla 1.5版本和UCenter 1.6版本.

现在基本流程已经完成.发现一个问题Joomla 1.5/1.6的onBeforeStoreUser事件对新注册用户时不好用.因为取不到新的注册信息也无法很好地中断注意流程.只能使用$mainframe->close()来强行中断.

正在考虑编写支持Joomla 1.7/2.5的新版本.

继续阅读 »

Discuz! X2源码分析-插件机制

以下是我的阅读笔记.方便日后记忆.

插件事件勾子默认入口:runhooks函数.主要运行插件初始函数和全局方法,如:common(),HookId().

先看源码,
source/function/function_core.php 约1191行开始:

function runhooks() {
if(!defined(‘HOOKTYPE’)) {
define(‘HOOKTYPE’, !defined(‘IN_MOBILE’) ? ‘hookscript’ : ‘hookscriptmobile’);
}
if(defined(‘CURMODULE’)) {
global $_G;
if($_G[‘setting’][‘plugins’][HOOKTYPE.’_common’]) {
hookscript(‘common’, ‘global’, ‘funcs’, array(), ‘common’);
}
hookscript(CURMODULE, $_G[‘basescript’]);
}
}

其中,HOOKTYPE当电脑浏览时是指hookscript,手机浏览时hookscriptmobile.

CURMODULE其实就是url中的$mod=XXX,其实就是常见的$action,也不是动作.以下代码是插件中的commom()方法.

if($_G[‘setting’][‘plugins’][HOOKTYPE.’_common’]) {
hookscript(‘common’, ‘global’, ‘funcs’, array(), ‘common’);
}

接着,$_G[‘basescript’]是当然的主程序名称,比如,forum.php?mod=XXX&do=XX,那么$_G[‘basescript’]就是forum.

hookscript运行在当前主程序下注册的相关函数.

接着是hookscript函数,这个是插件机制的重心.内容很多,我就直接在里面写注释好了.

/**
* @param String $script 事件勾子名称
* @param String $hscript 事件勾子所在的区域,常的有global,forum,home,member等,就是某个大块
* @param String $type 事件类型,一般都是函数形式,funcs
* @param Array $param 给给被调用的函数的参数.这是一个特殊的数组, 一般地,也会传递调用hookscript函数的函数的所有参数,读起来有点别扭:)有时候还会添加一些特殊的内容,如step等.
* @param Array $func 被调用的函数.虽然使用了=”的方式正义,但看过代码后,我觉得还是使用Array来正义它的类型会好些.
*/
function hookscript($script, $hscript, $type = ‘funcs’, $param = array(), $func = ”) {
global $_G;
static $pluginclasses;

#对家园这类勾子做特别处理.
if($hscript == ‘home’) {
if($script != ‘spacecp’) {
$script = ‘space_’.(!empty($_G[‘gp_do’]) ? $_G[‘gp_do’] : (!empty($_GET[‘do’]) ? $_GET[‘do’] : ”));
} else {
$script .= !empty($_G[‘gp_ac’]) ? ‘_’.$_G[‘gp_ac’] : (!empty($_GET[‘ac’]) ? ‘_’.$_GET[‘ac’] : ”);
}
}
#没有注册勾子,直接返回.
if(!isset($_G[‘setting’][HOOKTYPE][$hscript][$script][$type])) {
return;
}
#加载插件缓存
if(!isset($_G[‘cache’][‘plugin’])) {
loadcache(‘plugin’);
}

#引用插件主类所在文件
foreach((array)$_G[‘setting’][HOOKTYPE][$hscript][$script][‘module’] as $identifier => $include) {
$hooksadminid[$identifier] = !$_G[‘setting’][HOOKTYPE][$hscript][$script][‘adminid’][$identifier] || ($_G[‘setting’][HOOKTYPE][$hscript][$script][‘adminid’][$identifier] && $_G[‘adminid’] > 0 && $_G[‘setting’][‘hookscript’][$hscript][$script][‘adminid’][$identifier] >= $_G[‘adminid’]);
if($hooksadminid[$identifier]) {
@include_once DISCUZ_ROOT.’./source/plugin/’.$include.’.class.php’;
}
}
if(@is_array($_G[‘setting’][HOOKTYPE][$hscript][$script][$type])) {
$_G[‘inhookscript’] = true;
/**
* 自动校正第五个参数,以取得正确的调用函数.
* OK,$_G[‘setting’][HOOKTYPE][$hscript][$script][$type] = $_G[‘setting’][‘hookscript’][‘forum’][‘viewthread’][‘funcs’]
* print_r($_G[‘setting’][HOOKTYPE][$hscript][$script][$type]);
* 得到类似下面的结果:
* Array
* (
* [viewthread_posttop] => Array
* (
* [0] => Array
* (
* [0] => tbackup
* [1] => viewthread_posttop
* )
*
* )
* )
*/
$funcs = !$func ? $_G[‘setting’][HOOKTYPE][$hscript][$script][$type] : array($func => $_G[‘setting’][HOOKTYPE][$hscript][$script][$type][$func]);

#展开$funcs数组第一层:[viewthread_posttop] => Array
foreach($funcs as $hookkey => $hookfuncs) {
#再展开viewthread_posttop数组下的每个项:0~N
foreach($hookfuncs as $hookfunc) {
#$hookfunc[0]是插件类的identifier(例中的是:tbackup),而$hookfunc[1]则是类下面注册的一个方法(例中的是:viewthread_posttop)
if($hooksadminid[$hookfunc[0]]) {
$classkey = (HOOKTYPE != ‘hookscriptmobile’ ? ” : ‘mobile’).’plugin_’.($hookfunc[0].($hscript != ‘global’ ? ‘_’.$hscript : ”));
#无此类,跳过.
if(!class_exists($classkey)) {
continue;
}
#此类未在插件中注册,也跳过
if(!isset($pluginclasses[$classkey])) {
$pluginclasses[$classkey] = new $classkey;
}
#此类中无此方法,例中的是:viewthread_posttop,也跳过.
if(!method_exists($pluginclasses[$classkey], $hookfunc[1])) {
continue;
}
#执行类中的方法,例中的是:$pluginclasses[‘tbackup’]->viewthread_posttop($param)
$return = $pluginclasses[$classkey]->$hookfunc[1]($param);
#print_r($return);
#Array ( [0] => HI )
#如果返回的是数组,那么将$retgurn的$key和$value插入到$_G[‘setting’][‘pluginhooks’][$hookkey]中,在例中是$_G[‘setting’][‘pluginhooks’][‘tbackup’]
if(is_array($return)) {
if(!isset($_G[‘setting’][‘pluginhooks’][$hookkey]) || is_array($_G[‘setting’][‘pluginhooks’][$hookkey])) {
foreach($return as $k => $v) {
$_G[‘setting’][‘pluginhooks’][$hookkey][$k] .= $v;
}
}
} else {
/**
* $return非数组的情况下,
* 如果$_G[‘setting’][‘pluginhooks’][$hookkey]本身不是数组(一般说,它就是要求字符串的),那么直接把返回值$return追加到$_G[‘setting’][‘pluginhooks’][$hookkey]后在面
* */
if(!is_array($_G[‘setting’][‘pluginhooks’][$hookkey])) {
$_G[‘setting’][‘pluginhooks’][$hookkey] .= $return;
} else {
/**
* 如果$_G[‘setting’][‘pluginhooks’][$hookkey]本身就是数组(一般说,它就是要求返回数组的),那么把$return的每个KEY追加到
* $_G[‘setting’][‘pluginhooks’][$hookkey]对应的KEY后面.从而达到当$return为数组的情况一样的效果.
* */
foreach($_G[‘setting’][‘pluginhooks’][$hookkey] as $k => $v) {
$_G[‘setting’][‘pluginhooks’][$hookkey][$k] .= $return;
}
}
}
}
}
}
}
#更新标记,说明我已经跳出插件勾子啦!
$_G[‘inhookscript’] = false;
}

举个例子,实现在查看主题页面的下面添加”HI”.

class plugin_tbackup_forum extends plugin_tbackup {

function viewthread_bottom() {
return array(“HI”);
}
}

但是,有时候DZ定义的勾子不够多也不够细化,那么就只能请求全局勾子来帮下忙了.
全局勾子是hookscriptoutput,它本义是用于输出调试信息的.

/**
* hookscript的一个特例,当在某个模板准备输出时调用.
* @param String $tplfile 模板名,如viewthread
*
* */
function hookscriptoutput($tplfile) {
global $_G;
if(!empty($_G[‘hookscriptoutput’])) {
return;
}

/**
* 这块是手机的
* */
if(!empty($_G[‘gp_mobiledata’])) {
require_once libfile(‘class/mobiledata’);
$mobiledata = new mobiledata();
if($mobiledata->validator()) {
$mobiledata->outputvariables();
}
}
hookscript(‘global’, ‘global’);
if(defined(‘CURMODULE’)) {
$param = array(‘template’ => $tplfile, ‘message’ => $_G[‘hookscriptmessage’], ‘values’ => $_G[‘hookscriptvalues’]);
hookscript(CURMODULE, $_G[‘basescript’], ‘outputfuncs’, $param);
}
$_G[‘hookscriptoutput’] = true;
}

hookscriptoutput应该是用来DEBUG的,本身可以做的事不多,但是,如果你对DZ代码很了解的话,你可以修改任何GLOBAL中的内容,下面来个例子,用于修改每个帖子中的签名(DZ本身没有修改签名的勾子).

class plugin_tbackup_forum extends plugin_tbackup {

function viewthread_output($param) {
global $postlist;
foreach ((array) $postlist as $k=>$post) {
$postlist[$k][‘signature’] = “HI,Tim”;
}

}
}

例中,通过global $postlist;来引入全局程序中的$postlist也就是帖子列表.然后一个foreaech把$post里的signature修改掉.有心的朋友可以扩展下,$postlist[$k][‘signature’] = “HI,Tim”;可以改成一个过滤函数,那么不就可以过滤掉一些你不喜欢的签名了吗?

继续阅读 »