在PwBaseController  里面,会有这个方法的存在

/**
* action Hook 注册
*
* @param string $registerKey 扩展点别名
* @param PwBaseHookService $bp
* @throws PwException
* @return void
*/
protected function runHook($registerKey, $bp) {
if (!$registerKey) return;
if (!$bp instanceof PwBaseHookService) {
throw new PwException('class.type.fail',
array(
'{parm1}' => 'src.library.base.PwBaseController.runHook',
'{parm2}' => 'PwBaseHookService',
'{parm3}' => get_class($bp)));
}
if (!$filters = PwHook::getRegistry($registerKey)) return;
if (!$filters = PwHook::resolveActionHook($filters, $bp)) return;
$args = func_get_args();
$_filters = array();
foreach ($filters as $key => $value) {
$args[0] = isset($value['method']) ? $value['method'] : '';
$_filters[] = array('class' => $value['class'], 'args' => $args);
}
$this->resolveActionFilter($_filters);
}

我们先不理这个东西是什么,看它到底是怎样调用的

  

/**
* 发帖
*/
public function doaddAction() { list($title, $content, $topictype, $subtopictype, $reply_notice, $hide) = $this->getInput(array('atc_title', 'atc_content', 'topictype', 'sub_topictype', 'reply_notice', 'hide'), 'post');
$pwPost = $this->post;
$this->runHook('c_post_doadd', $pwPost); $postDm = $pwPost->getDm();
$postDm->setTitle($title)
->setContent($content)
->setHide($hide)
->setReplyNotice($reply_notice); //set topic type
$topictype_id = $subtopictype ? $subtopictype : $topictype;
$topictype_id && $postDm->setTopictype($topictype_id); if (($result = $pwPost->execute($postDm)) !== true) {
$data = $result->getData();
$data && $this->addMessage($data, 'data');
$this->showError($result->getError());
}
$tid = $pwPost->getNewId(); $this->showMessage('success', 'bbs/read/run/?tid=' . $tid . '&fid=' . $pwPost->forum->fid, true);
}

  

$this->runHook('c_post_doadd', $pwPost);

之前发帖的时候发现页面有添加话题的内容,但是在控制器入面却没有发现有这种逻辑的操作,后来才知道是通过注入去操作的,我们看看数据库入面的纪录

再看看它们是怎样定义的

/**
* 帖子发布 - 话题相关
*
* @author jinlong.panjl <jinlong.panjl@aliyun-inc.com>
* @copyright ©2003-2103 phpwind.com
* @license http://www.phpwind.com
* @version $Id$
* @package wind
*/
class PwPostDoTagInjector extends PwBaseHookInjector { public function doadd() {
$tagNames = (array)$this->getInput('tagnames', 'post');
if (!is_array($tagNames) || !count($tagNames)) return;
Wind::import('SRV:forum.srv.post.do.PwPostDoTag');
return new PwPostDoTag($this->bp,$tagNames);
} public function domodify() {
$tagNames = (array)$this->getInput('tagnames', 'post');
Wind::import('SRV:forum.srv.post.do.PwPostDoTag');
return new PwPostDoTag($this->bp,$tagNames);
}
}

  

doadd 这个方法就算添加标签的

它的父类是什么玩意

<?php
defined('WEKIT_VERSION') || exit('Forbidden'); Wind::import('WIND:filter.WindActionFilter'); /**
* PwHook action拦截过滤器抽象接口定义
*
* 通过继承该接口,可以实现在Controller层注入扩展实现.该接口默认调用'run'方法.
* 支持多参数扩展.
* @author Qiong Wu <papa0924@gmail.com> 2011-12-2
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
* @version $Id: PwBaseHookInjector.php 8692 2012-04-24 05:56:29Z jieyin $
* @package src
* @subpackage library.filter
*/
abstract class PwBaseHookInjector extends WindActionFilter { private $callback = 'run';
private $args = array();
/**
* @var PwBaseHookService
*/
protected $bp = null; /**
* @param WindForward $forward
* @param WindErrorMessage $errorMessage
* @param WindRouter $router
* @param array $args
*/
public function __construct($forward, $errorMessage, $router, $args = array()) {
parent::__construct($forward, $errorMessage, $router);
!empty($args[0]) && $this->callback = $args[0];
isset($args[1]) && $this->bp = $args[1];
if (count($args) > 2) {
unset($args[0], $args[1]);
$this->args = $args;
}
} /* (non-PHPdoc)
* @see WindHandlerInterceptor::preHandle()
*/
public function preHandle() {
if (!method_exists($this, $this->callback)) return;
$injector = call_user_func_array(array($this, $this->callback), $this->args);
if ($injector) $this->bp->appendDo($injector);
} /* (non-PHPdoc)
* @see WindHandlerInterceptor::postHandle()
*/
public function postHandle() {} }
?>

原来是继承了过滤器,呵呵,所以这个比较强大啊,可以这样用

我们在看看上面控制器的这个方法 resolveActionFilter

/**
* action过滤链策略部署
*
* @example <pre>
* $filters = array(array('expression'=>'', 'class'=>'',
* args=array()));
* </pre>
* @param array $filters
* @return void
*/
protected function resolveActionFilter($filters) {
if (!$filters) return;
$chain = WindFactory::createInstance('WindHandlerInterceptorChain');
$args = array($this->getForward(), $this->getErrorMessage(), null);
foreach ((array) $filters as $value) {
$chain->addInterceptors(
WindFactory::createInstance(Wind::import($value['class']),
(empty($value['args']) ? $args : array_merge($args, array($value['args'])))));
}
$chain->getHandler()->handle();
}

  流程是这样的,先建立过滤链 ,把过滤器一一添加实例化,哈哈,跟我们之前的没什么区别

  但是事情还没有结速

  

class PwPostDoTag extends PwPostDoBase {

	private $loginUser;
private $defaultType = 'threads';
private $tagNames = array();
private $typeId = ''; public function __construct(PwPost $pwpost,$tagNames) {
$this->loginUser = $pwpost->user;
$tagNames = $tagNames ? $tagNames : array();
$this->tagNames = array_unique($tagNames);
$this->typeId = $this->_getService()->getTypeIdByTypeName($this->defaultType);
} public function addThread($tid) {
$this->_getService()->addTags($this->_buildTagDm($tid));
} public function updateThread($tid) {
$this->_getService()->updateTags($this->typeId,$tid,$this->_buildTagDm($tid));
} public function getDm() {
return new PwTagDm();
} public function dataProcessing($postDm) {
if (!is_array($this->tagNames) || !$this->tagNames) return $postDm; $postDm->setTags(implode(',',$this->tagNames));
return $postDm;
} private function _buildTagDm($tid) {
if (!is_array($this->tagNames) || !$this->tagNames) return false;
$dmArray = array();
foreach ($this->tagNames as $value) {
$value = trim($value);
$dm = $this->getDm();
$dmArray[$value] =
$dm->setName($value)
->setTypeId($this->typeId)
->setParamId($tid)
->setIfhot(1)
->setCreateUid($this->loginUser->uid)
;
}
return $dmArray;
} public function check($postDm) {
if (!is_array($this->tagNames) || !$this->tagNames) return true;
$count = count($this->tagNames);
foreach ($this->tagNames as $v) {
$dm = $this->getDm();
$dm->setName($v);
if(($return = $dm->beforeAdd()) instanceof PwError) return $return;
}
if ($count > 5) {
return new PwError("Tag:tagnum.exceed");
}
if ($count && $this->loginUser->getPermission('tag_allow_add') < 1) {
return new PwError("TAG:right.tag_allow_add.error");
}
return true;
} /**
* Enter description here ...
*
* @return PwTagService
*/
protected function _getService() {
return Wekit::load('tag.srv.PwTagService');
}
}

  那么 addThread 是在什么时候调用的呢,又是怎样调用的呢 看这里

  

/**
* @see PwPostAction.afterRun
*/
public function afterRun() {
$this->runDo('addThread', $this->tid);
}

  这个类是 PwTopicPost 也正是我们在控制器里面刚刚实例化的 ,我们断点调式下看看 

  关键在这里

  

/* (non-PHPdoc)
* @see WindHandlerInterceptor::preHandle()
*/
public function preHandle() {
if (!method_exists($this, $this->callback)) return;
$injector = call_user_func_array(array($this, $this->callback), $this->args);
if ($injector) $this->bp->appendDo($injector);
}

  把过滤器又加入到_do里面,不知道为什么要这样呢

  $this->bp的值是多少呢

  

   原来是这个pwPost

class PwPost extends PwBaseHookService {

	public $action;
public $forum;
public $user;
public $special; // 帖子类型 public function __construct(PwPostAction $action) {
$this->action = $action;
$this->forum = $action->forum;
$this->user = $action->user;
$this->special = $action->getSpecial(); /** hook **/
$this->action->setSrv($this);
} /**
* 发帖之前检测
*
* @return bool
*/
public function check() {
if (($result = $this->isInit()) !== true) {
return new PwError('data.error');
}
if (($result = $this->checkForum()) !== true) {
return $result;
}
if (($result = $this->checkPost()) !== true) {
return $result;
}
if ($this->isBan()) {
return new PwError('ban');
}
if (($result = $this->action->check()) !== true) {
return $result;
}
return true;
} /**
* 初始化信息是否满足要求
*
* @return bool
*/
public function isInit() {
return $this->action->isInit();
} /**
* 检测是否拥有该版操作权限
*
* @return bool
*/
public function checkForum() {
if (!$this->forum->isForum()) {
return new PwError('BBS:post.forum.not.exists');
}
if (($result = $this->forum->allowVisit($this->user)) !== true) {
return new PwError('BBS:forum.permissions.visit.allow',
array('{grouptitle}' => $this->user->getGroupInfo('name')));
}
return true;
} /**
* 检测是否允许发帖
*
* @return bool
*/
public function checkPost() {
if ($this->user->groupid == 7) {
return new PwError('REG_CHECK');
}
/*
$config = Wekit::C('bbs');
if ($config['post.timing.open'] && !$this->user->inGroup($config['post.timing.groups']) && !self::inTime($config['post.timing.start_hour'], $config['post.timing.start_min'], $config['post.timing.end_hour'], $config['post.timing.end_min'])) {
return new PwError('BBS:post.timing');
}
*/
return true;
} /**
* 检测用户是否被禁言
*
* @return bool
*/
public function isBan() {
if ($this->user->gid == 6) {
Wind::import('SRV:user.srv.PwBanBp');
$banBp = new PwBanBp($this->user->uid);
$memberid = 0;
if (false === $banBp->checkIfBanSpeak()) {
$memberid = $banBp->recoveryBanSpeaKError();
} elseif ($banBp->endDateTimeBanSpeak()) {
$memberid = $banBp->callEndDateTimeBanSpeak();
}
if ($memberid) {
$this->user->info['groups'] = '';
$this->user->info['groupid'] = 0;
$this->user->info['memberid'] = $memberid;
$this->user->groups = array($memberid);
$this->user->resetGid($memberid);
return false;
}
return true;
}
return false;
} public function getDm() {
return $this->action->getDm();
} /**
* 各应用获取该用户dm来设置,以达到更新用户信息的目的
*
* @return object PwUserInfoDm
*/
public function getUserDm() {
return $this->action->getUserDm();
} public function getAttachs() {
return $this->action->getAttachs();
} /**
* 发布
*
* @param object $postDm 帖子数据模型
* @return bool
*/
public function execute(PwPostDm $postDm) {
if (($result = $this->action->beforeRun($postDm)) instanceof PwError) {
return $result;
}
if (($result = $this->action->dataProcessing($postDm)) !== true) {
return $result;
}
if (($result = $this->action->execute()) !== true) {
return $result;
}
$this->action->afterRun();
$this->updateUser();
return true;
} public function getInfo() {
return $this->action->getInfo();
} public function getNewId() {
return $this->action->getNewId();
} public function getDisabled() {
return $this->action->isDisabled();
} /**
* 更新用户信息 /积分/发帖数/等
*/
public function updateUser() {
Wind::import('SRV:credit.bo.PwCreditBo');
$credit = PwCreditBo::getInstance();
if ($operation = $this->action->getCreditOperate()) {
$credit->operate($operation, $this->user, true,
array('forumname' => $this->forum->foruminfo['name']),
$this->forum->getCreditSet($operation));
}
$credit->execute();
$this->action->updateUser();
if ($userDm = $this->action->getUserDm(false)) {
Wekit::load('user.PwUser')->editUser($userDm, PwUser::FETCH_DATA);
}
} public function appendDo($do) {
$this->action->appendDo($do);
} public function runDo($method) {
$args = func_get_args();
call_user_func_array(array($this->action, 'runDo'), $args);
}

  

原来是这样,看到这里基本明白啦

 

基本上发帖中就要牵涉到这里操作了,如果第三方插件要加入的话就要加上服务当中 

话题对应的hook 是 c_post_doadd

而发帖本身的hook是 m_PwTopicPost

来看看它是怎样定义的

<?php
defined('WEKIT_VERSION') || exit('Forbidden'); Wind::import('SRV:forum.srv.post.do.PwPostDoBase');
/**
* 帖子发布 - 话题
*
* @author jinlong.panjl <jinlong.panjl@aliyun-inc.com>
* @copyright ©2003-2103 phpwind.com
* @license http://www.phpwind.com
* @version $Id$
* @package wind
*/
class PwReplyDoRemind extends PwPostDoBase { private $loginUser;
private $_reminds = array();
private $_atc_title;
private $_maxNum; public function __construct(PwPost $pwpost) {
$this->loginUser = $pwpost->user;
$this->_maxNum = $this->loginUser->getPermission('remind_max_num');
} public function addPost($pid, $tid) {
$this->_addRemind($pid, $tid);
} public function updatePost($pid, $tid) {
$this->_addRemind($pid, $tid);
} public function dataProcessing($postDm) {
if ($this->_check() !== true) return $postDm;
$atc_content = $postDm->getField('content');
$atc_content = preg_replace('/\[quote(=.+?\,\d+)?\].*?\[\/quote\]/is', '', $atc_content);
$this->_atc_title = Pw::substrs(trim(Pw::stripWindCode($atc_content,true)),20); $reminds = $this->_getRemindService()->bulidRemind($atc_content);
$this->_reminds = $this->_getRemindService()->buildUsers($this->loginUser->uid,$reminds,$this->_maxNum);
$reminds = $this->_getRemindService()->formatReminds($this->_reminds);
$postDm->setReminds($reminds);
return $postDm;
} private function _addRemind($pid, $tid) {
if ($this->_check() !== true) return false;
if (!$this->_reminds) return false;
$reminds = ($this->_maxNum && count($this->_reminds) > $this->_maxNum) ? array_slice($this->_reminds, 0, $this->_maxNum) : $this->_reminds;
$remindUids = array_keys($reminds);
$this->_getRemindService()->addRemind($this->loginUser->uid, $remindUids); //发送通知
$extendParams = array(
'remindUid' => $this->loginUser->uid,
'title' => $this->_atc_title,
'remindUsername' => $this->loginUser->username,
'notice' => '在回帖 <a href="' . WindUrlHelper::createUrl('bbs/read/run', array('tid'=>$tid), $pid) . '" target="_blank">' . $this->_atc_title . '</a> @了您',
);
// 是否黑名单
$remindUids = $this->_checkBlack($remindUids);
foreach ($remindUids as $uid) {
$this->_getPwNoticeService()->sendNotice($uid,'remind',$pid,$extendParams);
}
} private function _check() {
if ($this->loginUser->getPermission('remind_open') < 1) {
return new PwError("bbs:remind.remind_open.error");
}
return true;
} /**
* 是否开启权限
*
* @param array $remindUids
* @return bool
*/
private function _checkBlack($remindUids) {
$result = Wekit::load('user.PwUserBlack')->checkUserBlack($this->loginUser->uid, $remindUids);
if ($result) {
$remindUids = array_diff($remindUids,$result);
}
return $remindUids;
} /**
* @return PwNoticeService
*/
protected function _getPwNoticeService(){
return Wekit::load('message.srv.PwNoticeService');
} /**
* PwRemindService
*
* @return PwRemindService
*/
private function _getRemindService(){
return Wekit::load('remind.srv.PwRemindService');
}
}

  不同的类有不同的方法,可能就是调用时机不同,责任不同,总之就比较复杂

 

   

 
												

捣蛋phpwind控制器注入的更多相关文章

  1. 捣蛋phpwind之WindFrameWork

    一直都有关注phpwind这个开源产品,从9.0开始就好关注拉,因为官方说把之前的代码重写了一遍,融入了windFramework这个框架,代码真的挺优美的,今日在做社区的一些功能,心血来潮就参考了p ...

  2. 捣蛋phpwind过滤器执行流程

    从上一篇我们就大概就知道过滤器的定义和怎样去配置,这一节来说说执行流程 public function run($handlerAdapter = null) { $handlerAdapter != ...

  3. 007.ASP.NET MVC控制器依赖注入

    原文链接:http://www.codeproject.com/Articles/560798/ASP-NET-MVC-Controller-Dependency-Injection-for-Be 前 ...

  4. ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下

    ADO.NET   一.ADO.NET概要 ADO.NET是.NET框架中的重要组件,主要用于完成C#应用程序访问数据库 二.ADO.NET的组成 ①System.Data  → DataTable, ...

  5. ASP.NET MVC 控制器激活(二)

    ASP.NET MVC 控制器激活(二) 前言 在之前的篇幅中,用文字和图像来表示了控制器的激活过程,描述的角度都是从框架默认实现的角度去进行描述的,这样也使得大家都可以清楚的知道激活的过程以及其中涉 ...

  6. ASP.NET MVC 控制器激活(三)

    ASP.NET MVC 控制器激活(三) 前言 在上个篇幅中说到从控制器工厂的GetControllerInstance()方法来执行控制器的注入,本篇要讲是在GetControllerInstanc ...

  7. angularJS推荐显示注入写法

    使用js压缩工具时发现压缩之后的控制器注入参数由原来的$scope变成了a,b...这样的字母而导致js失效,那么我们推荐使用完整的显示注入方式来解决此问题! //隐式注入的写法 angular.mo ...

  8. MVC 控制器激活

    MVC 控制器激活 ASP.NET MVC 控制器激活(三) 前言 在上个篇幅中说到从控制器工厂的GetControllerInstance()方法来执行控制器的注入,本篇要讲是在GetControl ...

  9. ASP.NET MVC Autofac依赖注入的一点小心得(包含特性注入)

    前言 IOC的重要性 大家都清楚..便利也都知道..新的ASP.NET Core也大量使用了这种手法.. 一直憋着没写ASP.NET Core的文章..还是怕误导大家.. 今天这篇也不是讲Core的 ...

随机推荐

  1. asp.net收藏和设为首页的代码

    1:设为首页 <a href="javascript:void(0);" id="setHomePage" onclick="this.styl ...

  2. git忽略文件【转】

    转自: http://cwind.iteye.com/blog/1666646 有很多文件不必使用git管理.例如Eclipse或其他IDE生成的项目文件,编译生成的各种目标或临时文件等.使用git ...

  3. POJ-3669 Meteor Shower(bfs)

    http://poj.org/problem?id=3669 注意理解题意:有m颗行星将会落在方格中(第一象限),第i颗行星在ti时间会摧毁(xi,yi)这个点和四周相邻的点,一个人开始在原点,然后只 ...

  4. ios用户控件

    22:48:452015-03-16说道用控件,很地东方都在用.用好了,可以加快开发进度,提高可维护性,程序的稳定,健壮性,用不好,也可以提高经验值啊,下次就好了,算是学习成本吧. 不同语言,不同项目 ...

  5. 【AStar】初赛第一场

    1. All X1.1 基本思路k和c的范围都不大,因此可以考虑迭代找循环节,然后求余数,判定是否相等.这题还是挺简单的.1.2 代码 /* 5690 */ #include <iostream ...

  6. mongoDB使用复制还原数据库节省空间

    用db.copyDatabase可以备份复制数据的方法. 1.db.copyDatabase("from","to","127.0.0.1:16161 ...

  7. JS获取系统的指定定年月日

    /** * 获取系统当前时间 */ function getNowYearMouth(){ var date=new Date; var nowYearMouth=date.getMonth()+1; ...

  8. 监控tomcat性能

    tomcat经常被用作中间件,也有直接作WEB的,自带的工具不是很给力,推荐以下的办法 工具/原料 javamelody 方法/步骤   下载 javamelody.jar和 jrobin-x.jar ...

  9. 基于HtmlUnit的模板的网页数据抽取

    既然方向定了,就开始做实验室吧,做舆情分析,首先就是要收集相关的语料 正好实验室有同学在做标化院的信息抽取抽取这块 于是把程序拿过来研究研究正好 完整程序在126邮箱共享: 可下载数:20  共享连接 ...

  10. 多线程-NSOperation中使用ASIHttpRequest注意事项

    最近做的iPhone项目中有一如下功能: app在用户许可后将本地Photos的照片上传到服务器,期间用户可以做其他任何操作,等上传成功后弹出一个toast通知用户. 原先的代码结构是: 获取照片的操 ...