2011-10-9 * @copyright ©2003-2103 phpwind.com * @license http://www.windframework.com * @version $Id: Wind.php 3859 2012-12-18 09:25:51Z yishuo $ */ class Wind { public static $_imports = array(); public static $_classes = array(); private static $_extensions = 'php'; private static $_isAutoLoad = true; private static $_namespace = array(); private static $_includePaths = array(); /** * * @var AbstractWindFrontController */ private static $_front = null; /** * command line mode application 应用入口 * * @param string $appName * @param string|array $config * @return WindCommandFrontController */ public static function commandApplication($appName = '', $config = array()) { if (self::$_front === null) { self::$_classes['WindCommandFrontController'] = 'command/WindCommandFrontController'; self::$_front = new WindCommandFrontController($appName, $config); } return self::$_front; } /** * Web Application应用入口 * * @param string $appName * @param string|array $config * @return WindWebApplication */ public static function application($appName = '', $config = array()) { if (self::$_front === null) { self::$_classes['WindWebFrontController'] = 'web/WindWebFrontController'; //zzcity self::$_front = new WindWebFrontController($appName, $config); } return self::$_front; } /** * 获取系统组建 * * @param string $alias * @param array $args * @return Ambigous */ public static function getComponent($alias, $args = array()) { return WindFactory::_getInstance()->getInstance($alias, $args); } /** * 注册系统组建 * * 对象方式注册: * $converter = new WindGeneralConverter(); * Wind::registeComponent($converter,'windConverter',singleton); * 定义方式注册: * Wind::registeComponent(array('path' => * 'WIND:convert.WindGeneralConverter', 'scope' => 'singleton'), * 'windConverter'); * * @param object|array $componentInstance * @param string $componentName * @param string $scope * @return boolean */ public static function registeComponent($componentInstance, $componentName, $scope = 'application') { if (is_array($componentInstance)) { isset($componentInstance['scope']) || $componentInstance['scope'] = $scope; WindFactory::_getInstance()->loadClassDefinitions( array($componentName => $componentInstance)); } elseif (is_object($componentInstance)) { WindFactory::_getInstance()->registInstance($componentInstance, $componentName, $scope); } else throw new WindException('registe component fail, array or object is required', WindException::ERROR_PARAMETER_TYPE_ERROR); } /** * * @see WindFrontController::getAppName() * @return string */ public static function getAppName() { return self::$_front->getAppName(); } /** * 返回当前的app应用 * * @param string $appName * @see WindFrontController::getApp() * @return WindWebApplication */ public static function getApp() { return self::$_front->getApp(); } /** * 加载一个类或者加载一个包 * 如果加载的包中有子文件夹不进行循环加载 * 参数格式说明:'WIND:base.WFrontController' * WIND 注册的应用名称,应用名称与路径信息用':'号分隔 * base.WFrontController 相对的路径信息 * 如果不填写应用名称 ,例如'base.WFrontController',那么加载路径则相对于默认的应用路径 * 加载一个类的参数方式:'WIND:base.WFrontController' * 加载一个包的参数方式:'WIND:base.*' * * @param string $filePath * | 文件路径信息 或者className * @return string null */ public static function import($filePath) { if (!$filePath) return; if (isset(self::$_imports[$filePath])) return self::$_imports[$filePath]; if (($pos = strrpos($filePath, '.')) !== false) $fileName = substr($filePath, $pos + 1); elseif (($pos = strrpos($filePath, ':')) !== false) $fileName = substr($filePath, $pos + 1); else $fileName = $filePath; $isPackage = $fileName === '*'; if ($isPackage) { $filePath = substr($filePath, 0, $pos + 1); $dirPath = self::getRealPath(trim($filePath, '.'), false); self::register($dirPath, '', true); } else self::_setImport($fileName, $filePath); return $fileName; } //zzcity public static function zzimport($filePath) { if (!$filePath) return; if (isset(self::$_imports[$filePath])) return self::$_imports[$filePath]; if (($pos = strrpos($filePath, '.')) !== false) $fileName = substr($filePath, $pos + 1); elseif (($pos = strrpos($filePath, ':')) !== false) $fileName = substr($filePath, $pos + 1); else $fileName = $filePath; return $fileName; } /** * 将路径信息注册到命名空间,该方法不会覆盖已经定义过的命名空间 * * @param string $path * 需要注册的路径 * @param string $name * 路径别名 * @param boolean $includePath * | 是否同时定义includePath * @param boolean $reset * | 是否覆盖已经存在的定义,默认false * @return void * @throws Exception */ public static function register($path, $alias = '', $includePath = false, $reset = false) { if (!$path) return; if (!empty($alias)) { $alias = strtolower($alias); if (!isset(self::$_namespace[$alias]) || $reset) self::$_namespace[$alias] = rtrim( $path, '\\/') . DIRECTORY_SEPARATOR; } if ($includePath) { if (empty(self::$_includePaths)) { self::$_includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path())); if (($pos = array_search('.', self::$_includePaths, true)) !== false) unset( self::$_includePaths[$pos]); } array_unshift(self::$_includePaths, $path); if (set_include_path( '.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) { throw new Exception('[wind.register] set include path error.'); } } } /** * 返回命名空间的路径信息 * * @param string $namespace * @return string Ambigous multitype:> */ public static function getRootPath($namespace) { $namespace = strtolower($namespace); return isset(self::$_namespace[$namespace]) ? self::$_namespace[$namespace] : ''; } /** * 类文件自动加载方法 callback * * @param string $className * @param string $path * @return null */ public static function autoLoad($className, $path = '') { if ($path) include $path . '.' . self::$_extensions; elseif (isset(self::$_classes[$className])) { include self::$_classes[$className] . '.' . self::$_extensions; } else include $className . '.' . self::$_extensions; } /** * 解析路径信息,并返回路径的详情 * * @param string $filePath * 路径信息 * @param boolean $suffix * 是否存在文件后缀true,false,default * @return string array('isPackage','fileName','extension','realPath') */ public static function getRealPath($filePath, $suffix = '', $absolut = false) { if (false !== strpos($filePath, DIRECTORY_SEPARATOR)) return realpath($filePath); if (false !== ($pos = strpos($filePath, ':'))) { $namespace = self::getRootPath(substr($filePath, 0, $pos)); $filePath = substr($filePath, $pos + 1); } else $namespace = $absolut ? self::getRootPath(self::getAppName()) : ''; $filePath = str_replace('.', '/', $filePath); $namespace && $filePath = $namespace . $filePath; if ($suffix === '') return $filePath . '.' . self::$_extensions; if ($suffix === true && false !== ($pos = strrpos($filePath, '/'))) { $filePath[$pos] = '.'; return $filePath; } return $suffix ? $filePath . '.' . $suffix : $filePath; } /** * 解析路径信息,并返回路径的详情 * * @param string $filePath * 路径信息 * @param boolean $absolut * 是否返回绝对路径 * @return string array('isPackage','fileName','extension','realPath') */ public static function getRealDir($dirPath, $absolut = false) { if (false !== ($pos = strpos($dirPath, ':'))) { $namespace = self::getRootPath(substr($dirPath, 0, $pos)); $dirPath = substr($dirPath, $pos + 1); } else $namespace = $absolut ? self::getRootPath(self::getAppName()) : ''; $namespace && $dirPath = $namespace . str_replace('.', '/', $dirPath); return $dirPath; } /** * 初始化框架 */ public static function init() { function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0'); self::register(WIND_PATH, 'WIND', true); if (!self::$_isAutoLoad) return; if (function_exists('spl_autoload_register')) spl_autoload_register('Wind::autoLoad'); else self::$_isAutoLoad = false; self::_loadBaseLib(); } /** * * @param string $className * @param string $classPath * @return void */ private static function _setImport($className, $classPath) { self::$_imports[$classPath] = $className; if (!isset(self::$_classes[$className])) { $_classPath = self::getRealPath($classPath, false); self::$_classes[$className] = $_classPath; } else $_classPath = self::$_classes[$className]; if (!self::$_isAutoLoad) self::autoLoad($className, $_classPath); } /** * 加载核心层库函数 * * @return void */ private static function _loadBaseLib() { self::$_classes = array( 'AbstractWindBootstrap' => 'base/AbstractWindBootstrap', 'AbstractWindFrontController' => 'base/AbstractWindFrontController', //'AbstractWindApplication' => 'base/AbstractWindApplication', //zzcity 'IWindController' => 'base/IWindController', 'IWindRequest' => 'base/IWindRequest', 'IWindResponse' => 'base/IWindResponse', 'WindActionException' => 'base/WindActionException', 'WindEnableValidateModule' => 'base/WindEnableValidateModule', 'WindError' => 'base/WindError', 'WindErrorMessage' => 'base/WindErrorMessage', 'WindException' => 'base/WindException', 'WindFactory' => 'base/WindFactory', 'WindFinalException' => 'base/WindFinalException', 'WindForwardException' => 'base/WindForwardException', 'WindModule' => 'base/WindModule', 'WindActionFilter' => 'filter/WindActionFilter', 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', 'WindLogger' => 'log/WindLogger', 'WindLangResource' => 'i18n/WindLangResource', 'WindConfigParser' => 'parser/WindConfigParser', 'WindArray' => 'utility/WindArray', 'WindConvert' => 'utility/WindConvert', 'WindCookie' => 'utility/WindCookie', 'WindDate' => 'utility/WindDate', 'WindFile' => 'utility/WindFile', 'WindFolder' => 'utility/WindFolder', 'WindGeneralDate' => 'utility/WindGeneralDate', 'WindImage' => 'utility/WindImage', 'WindJson' => 'utility/WindJson', 'WindPack' => 'utility/WindPack', 'WindSecurity' => 'utility/WindSecurity', 'WindString' => 'utility/WindString', 'WindUrlHelper' => 'utility/WindUrlHelper', 'WindUtility' => 'utility/WindUtility', 'WindValidator' => 'utility/WindValidator'); } } wind::init(); abstract class AbstractWindApplication extends WindModule { /** * 请求对象 * * @var WindHttpRequest */ protected $request; /** * 响应对象 * * @var WindHttpResponse */ protected $response; /** * 组建工厂对象 * * @var WindFactory */ protected $factory = null; /** * 路由对象 * * @var WindRouter */ protected $handlerAdapter = null; /** * 应用初始化操作 * * @param WindHttpRequest $request * @param WindHttpResponse $response * @param WindFactory $factory */ public function __construct($request, $response, $factory) { $this->response = $response; $this->request = $request; $this->factory = $factory; } /** * 请求处理完毕后,进一步分发 * * @param WindForward $forward * @param boolean $display */ abstract public function doDispatch($forward); /** * 处理错误请求 * 根据错误请求的相关信息,将程序转向到错误处理句柄进行错误处理 * * @param WindErrorMessage $errorMessage * @param int $errorcode * @return void */ abstract protected function sendErrorMessage($errorMessage, $errorcode); /* * (non-PHPdoc) @see IWindApplication::run() */ public function run($handlerAdapter = null) { $handlerAdapter !== null && $this->handlerAdapter = $handlerAdapter; $module = $this->getModules(); $handlerPath = $module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . $module['controller-suffix']; $className = Wind::zzimport($handlerPath); //zzcity if (!class_exists($className)) throw new WindException( 'Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $handler = new $className(); $handler->setDelayAttributes( array( 'errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'))); $handlerAdapter !== null && $this->resolveActionFilters($handler); try { $handler->searchthreadAction(); // $forward = $handler->doAction($this->handlerAdapter); // $this->doDispatch($forward); //zzcity } catch (WindForwardException $e) { echo('[err]1'.$e->getMessage().'[/err]'); exit; // $this->doDispatch($e->getForward()); } catch (WindActionException $e) { echo('[err]2'.$e->getMessage().'[/err]'); exit; // $this->sendErrorMessage(($e->getError() ? $e->getError() : $e->getMessage()), // $e->getCode()); } catch (WindException $e) { echo('[err]3'.$e->getMessage().'[/err]'); exit; // $this->sendErrorMessage($e->getMessage(), $e->getCode()); } } /** * 添加module配置 * * controller * * Controller * * WIND:web.WindErrorHandler * * * * template * * htm * * @param string $name * module名称 * @param array $config * 配置数组 * @param boolean $replace * 如果module已经存在是否覆盖他 默认值为false不进行覆盖 * @return array */ public function setModules($name, $config, $replace = false) { if ($replace || !isset($this->_config['modules'][$name])) { $this->_config['modules'][$name] = (array) $config; } return $this->_config['modules'][$name]; } /** * 获得module配置,$name为空时返回当前module配置 * * @param string $name * module名称 默认为空 * @param boolean $merge * 合并默认值 * @return array * @throws WindActionException * @throws WindException */ public function getModules($name = '') { if ($name === '') $name = $this->handlerAdapter->getModule(); if ($name === 'pattern') $name = $this->handlerAdapter->getDefaultModule(); if ($name === 'default') return $this->_config['modules']['default']; $_module = $this->getConfig('modules', $name, array()); if (!isset($_module['_verified']) || $_module['_verified'] !== true) { if (empty($_module) && !empty($this->_config['modules']['pattern'])) { $_module = $this->_config['modules']['pattern']; } $_module && $_module = WindUtility::mergeArray($this->_config['modules']['default'], $_module); $_module_str = implode('#', $_module); if (strpos($_module_str, '{') !== false) { preg_match_all('/{(\w+)}/i', $_module_str, $matches); if (!empty($matches[1])) { $_replace = array(); foreach ($matches[1] as $key => $value) { if ($value === $this->handlerAdapter->getModuleKey()) $_replace['{' . $value . '}'] = $this->handlerAdapter->getModule(); elseif ($value === $this->handlerAdapter->getControllerKey()) $_replace['{' . $value . '}'] = $this->handlerAdapter->getController(); elseif ($value === $this->handlerAdapter->getActionKey()) $_replace['{' . $value . '}'] = $this->handlerAdapter->getAction(); else $_replace['{' . $value . '}'] = $this->request->getGet($value); } $_module_str = strtr($_module_str, $_replace); $_module = array_combine(array_keys($_module), explode('#', $_module_str)); } } $_module['_verified'] = true; $this->_config['modules'][$name] = $_module; } return $_module; } /** * 手动注册actionFilter * 参数为数组格式: * * @param array $filters */ public function registeActionFilter($filters) { if (!$filters) return; if (empty($this->_config['filters'])) $this->_config['filters'] = $filters; else $this->_config['filters'] += $filters; } /** * 解析action过滤链的配置信息 * * @param WindSimpleController $handler * @return void */ protected function resolveActionFilters(&$handler) { if (!$filters = $this->getConfig('filters')) return; /* @var $cache AbstractWindCache */ $_filters = array(); if ($cache = Wind::getComponent('windCache')) { $_filters = $cache->get('filters'); } $_token = $this->handlerAdapter->getModule() . '/' . $this->handlerAdapter->getController() . '/' . $this->handlerAdapter->getAction(); if (!isset($_filters[$_token])) { foreach ($filters as $_filter) { if (empty($_filter['class'])) continue; $_pattern = empty($_filter['pattern']) ? '' : $_filter['pattern']; unset($_filter['pattern']); if ($_pattern) { $_pattern = str_replace(array('*', '/'), array('\w*', '\/'), $_pattern); if (in_array($_pattern[0], array('~', '!'))) { $_pattern = substr($_pattern, 1); if (preg_match('/^' . $_pattern . '$/i', $_token)) continue; } else { if (!preg_match('/^' . $_pattern . '$/i', $_token)) continue; } } $_filters[$_token][] = $_filter; } $cache && $cache->set('filters', $_filters); } if (empty($_filters[$_token])) return; /* @var $proxy WindClassProxy */ $proxy = WindFactory::createInstance(Wind::import('WIND:filter.proxy.WindClassProxy')); $proxy->registerTargetObject($handler); foreach ($_filters[$_token] as $value) { if ($value['class']=='LIB:filter.PwCsrfTokenFilter') continue;//zzcity $proxy->registerEventListener( $this->factory->createInstance(Wind::import($value['class']), array( $handler->getForward(), $handler->getErrorMessage(), $this->handlerAdapter, $value)), 'doAction'); } $handler = $proxy; } /** * * @return WindHttpRequest */ public function getRequest() { return $this->request; } /** * * @return WindHttpResponse */ public function getResponse() { return $this->response; } /** * * @return WindFactory */ public function getFactory() { return $this->factory; } } /** * @author Jianmin Chen * @copyright ©2003-2103 phpwind.com * @license http://www.phpwind.com * @version $Id: wekit.php 22719 2012-12-26 12:44:12Z jieyin $ * @package wekit */ class Wekit { protected static $_config; protected static $_cache; protected static $_var = array(); protected static $_app; /** * 运行当前应用 * * @param string $name 应用名称默认'phpwind' * @param array $components 组建配置信息 该组建配置将会覆盖原组建配置,默认为空 */ public static function run($name = 'phpwind', $components = array()) { $config = WindUtility::mergeArray(include WEKIT_PATH . '../conf/application/default.php', include WEKIT_PATH . '../conf/application/' . $name . '.php'); if (!empty($components)) $config['components'] = (array) $components + $config['components']; /* @var $application WindWebFrontController */ $application = Wind::application($name, $config); $application->registeFilter(new PwFrontFilters($application)); $application->run(); } /** * phpwind初始化 * * @return void */ public static function init() { function_exists('set_magic_quotes_runtime') && @set_magic_quotes_runtime(0); $_conf = include WEKIT_PATH . '../conf/directory.php'; foreach ($_conf as $namespace => $path) { $realpath = realpath(WEKIT_PATH . $path); Wind::register($realpath, $namespace); define($namespace . '_PATH', $realpath . '/'); } Wind::register(WEKIT_PATH, 'WEKIT'); self::_loadBase(); } /** * 获取当前应用 * * @return phpwindBoot */ public static function app() { return self::$_app; } /** * 创建当前应用实例 */ public static function createapp($appName) { if (!is_object(self::$_app)) { self::$_var = include CONF_PATH . 'baseconfig.php'; self::$_cache = new PwCache(); if (self::$_var['dbcache'] && self::$_cache->isDbCache()) { PwLoader::importCache(include CONF_PATH . 'cacheService.php'); } $class = Wind::import('SRC:bootstrap.' . $appName . 'Boot'); //zzcity phpwindBoot self::$_app = new $class(); self::$_config = self::$_app->getConfig(); define('WEKIT_TIMESTAMP', self::$_app->getTime()); } } /** * 获取实例 * * @param string $path 路径 * @param string $loadway 加载方式 * @param array $args 参数 * @return object */ public static function getInstance($path, $loadway = '', $args = array()) { switch ($loadway) { case 'loadDao': return Wekit::loadDao($path); case 'load': return Wekit::load($path); case 'static': return Wind::import($path); default: $reflection = new ReflectionClass(Wind::import($path)); return call_user_func_array(array($reflection, 'newInstance'), $args); } } /** * 加载类库(单例) * * @param string $path 路径 * @return object */ public static function load($path) { return PwLoader::load($path); } /** * 加载Dao(单例) * * @param string $path 路径 * @return object */ public static function loadDao($path) { return PwLoader::loadDao($path); } /** * 获取Dao组合(单例) * * @param int $index 索引键 * @param array $daoMap dao列表 * @param string $vkey 区分符 * @return object */ public static function loadDaoFromMap($index, $daoMap, $vkey) { return PwLoader::loadDaoFromMap($index, $daoMap, $vkey); } /** * 设置全局变量 * * @param array|string|object $data * @param string $key * @see WindWebApplication::setGlobal */ public static function setGlobal($data, $key = '') { if ($key) $_G[$key] = $data; else { if (is_object($data)) $data = get_object_vars($data); $_G = $data; } Wind::getApp()->getResponse()->setData($_G, 'G', true); } /** * 获得全局变量 * * @return array|string|object * @see WindWebApplication::getGlobal */ public static function getGlobal() { $_args = func_get_args(); array_unshift($_args, 'G'); return call_user_func_array(array(Wind::getApp()->getResponse(), 'getData'), $_args); } /** * 获取当前登录用户 * * @return PwUserBo */ public static function getLoginUser() { return self::$_app->getLoginUser(); } /** * 获取全局基本配置 * * @param string $var * @return mixed */ public static function V($var) { return self::$_var[$var]; } /** * 获取应用配置 config * * @param string $namespace 配置域 * @param string $key 配置键值 * @return mixted */ public static function C($namespace = '', $key = '') { if ($namespace) { return $key ? self::$_config->$namespace->get($key) : self::$_config->$namespace->toArray(); } return self::$_config; } /** * 获取通用缓存服务 * * @return object */ public static function cache() { return self::$_cache; } /** * 预加载相关类文件 * * @return void */ protected static function _loadBase() { Wind::import('WIND:utility.WindFolder'); Wind::import('WIND:utility.WindJson'); Wind::import('WIND:utility.WindFile'); Wind::import('WIND:utility.WindValidator'); Wind::import('WIND:utility.WindCookie'); Wind::import('WIND:utility.WindSecurity'); Wind::import('WIND:utility.WindString'); Wind::import('WIND:utility.WindConvert'); Wind::import('LIB:base.*'); Wind::import('LIB:engine.extension.viewer.*'); Wind::import('LIB:engine.component.*'); Wind::import('LIB:engine.error.*'); Wind::import('LIB:engine.exception.*'); Wind::import('LIB:engine.hook.*'); Wind::import('LIB:Pw'); Wind::import('LIB:PwLoader'); Wind::import('LIB:filter.PwFrontFilters'); Wind::import('SRV:cache.PwCache'); Wind::import('SRV:config.bo.PwConfigBo'); Wind::import('SRV:config.srv.PwConfigSet'); Wind::import('WINDID:library.Windid'); Wind::import('WINDID:WindidApi'); Wind::import('SRV:user.bo.PwUserBo'); } } Wekit::init(); Wind::import('WIND:utility.WindJson'); Wind::import('SRV:credit.bo.PwCreditBo'); Wind::import('WIND:web.WindSimpleController');//zzcity Wind::import('WIND:web.WindController');//zzcity /** * 帖子dao服务 * * @author Jianmin Chen * @copyright ©2003-2103 phpwind.com * @license http://www.phpwind.com * @version $Id: PwThreadMergeDao.php 21335 2012-12-05 03:39:26Z jieyin $ * @package forum */ class PwThreadMergeDao extends PwBaseDao { protected $_table = 'bbs_threads'; protected $_mergeTable = 'bbs_threads_content'; protected $_dataStruct = array(); public function countSearchThread($field) { list($where, $arg, $merge) = $this->_buildCondition($field); $_mergeTable = $merge ? $this->_bindTable(' LEFT JOIN %s b ON a.tid=b.tid', $this->getTable($this->_mergeTable)) : ''; $sql = $this->_bindSql('SELECT COUNT(*) AS sum FROM %s a %s WHERE %s', $this->getTable(), $_mergeTable, $where); $smt = $this->getConnection()->createStatement($sql); return $smt->getValue($arg); } public function searchThread($fetch, $field, $orderby, $limit, $offset) { list($where, $arg, $merge) = $this->_buildCondition($field); $order = $this->_buildOrderby($orderby); list($select, $merge) = $this->_buildFetch($fetch, $merge); $_mergeTable = $merge ? $this->_bindTable(' LEFT JOIN %s b ON a.tid=b.tid', $this->getTable($this->_mergeTable)) : ''; $sql = $this->_bindSql('SELECT %s FROM %s a %s WHERE %s %s %s', $select, $this->getTable(), $_mergeTable, $where, $order, $this->sqlLimit($limit, $offset)); $smt = $this->getConnection()->createStatement($sql); return $smt->queryAll($arg, 'tid'); } protected function _buildFetch($fetch, $merge) { $select = 'a.*'; if (($fetch & 3) == 3) { $select = '*'; $merge = 1; } elseif (($fetch & 3) == 2) { $select = 'b.*'; $merge = 1; } return array($select, $merge); } protected function _buildCondition($field) { $merge = 0; $where = '1'; $arg = array(); foreach ($field as $key => $value) { switch ($key) { case 'tid': $where .= ' AND tid ' . $this->_sqlIn($value, $arg); break; case 'fid': $where .= ' AND a.fid ' . $this->_sqlIn($value, $arg); break; case 'topic_type': $where .= ' AND a.topic_type' . $this->_sqlIn($value, $arg); break; case 'disabled': $where .= ' AND a.disabled=?'; $arg[] = $value; break; case 'created_userid': $where .= ' AND a.created_userid ' . $this->_sqlIn($value, $arg); break; case 'title_keyword': // $where .= ' AND a.subject LIKE ?'; // $arg[] = "%$value%"; $where .= ' AND a.subject = ?'; $arg[] = "$value"; break; case 'content_keyword': $where .= ' AND b.content LIKE ?'; $arg[] = "%$value%"; $merge = 1; break; case 'title_and_content_keyword': $where .= ' AND (a.subject LIKE ? OR b.content LIKE ?)'; $arg[] = "%$value%"; $arg[] = "%$value%"; $merge = 1; break; case 'created_time_start': $where .= ' AND a.created_time>?'; $arg[] = $value; break; case 'created_time_end': $where .= ' AND a.created_time ?'; $arg[] = $value; break; case 'lastpost_time_end': $where .= ' AND lastpost_time < ?'; $arg[] = $value; break; case 'digest': $where .= ' AND a.digest=?'; $arg[] = $value; break; case 'hasimage': $where .= ' AND a.ifupload&1=' . intval($value); break; case 'special': $where .= ' AND special ' . $this->_sqlIn($value, $arg); break; case 'topped': $where .= ' AND topped ' . $this->_sqlIn($value, $arg); break; case 'hits_start': $where .= ' AND a.hits>?'; $arg[] = $value; break; case 'hits_end': $where .= ' AND a.hits?'; $arg[] = $value; break; case 'replies_end': $where .= ' AND a.replies $value) { switch ($key) { case 'created_time': $array[] = 'a.created_time ' . ($value ? 'ASC' : 'DESC'); break; case 'lastpost_time': $array[] = 'lastpost_time ' . ($value ? 'ASC' : 'DESC'); break; case 'replies': $array[] = 'replies ' . ($value ? 'ASC' : 'DESC'); break; case 'hits': $array[] = 'hits ' . ($value ? 'ASC' : 'DESC'); break; case 'like': $array[] = 'like_count ' . ($value ? 'ASC' : 'DESC'); break; } } return $array ? ' ORDER BY ' . implode(',', $array) : ''; } protected function _sqlIn($value, &$arg) { if (is_array($value)) { return ' IN ' . $this->sqlImplode($value); } $arg[] = $value; return '=?'; } } /** * 帖子基础服务 * * @author Jianmin Chen * @copyright ©2003-2103 phpwind.com * @license http://www.phpwind.com * @version $Id: PwThread.php 22488 2012-12-25 02:57:19Z xiaoxia.xuxx $ * @package forum */ class PwThread { const FETCH_MAIN = 1; //帖子基本信息 const FETCH_CONTENT = 2; //帖子内容相关信息 const FETCH_ALL = 3; const SPECIAL_SORT_TOP1 = 101; const SPECIAL_SORT_TOP2 = 102; const SPECIAL_SORT_TOP3 = 103; const STATUS_LOCKED = 1; const STATUS_CLOSED = 2; const STATUS_DOWNED = 3; const STATUS_OPERATORLOG = 4;//是否有帖子操作日志 /** * 获取单个帖子信息 * * @param int $tid 帖子id * @param int $fetchmode 帖子资料 <必然为FETCH_*的一种或者组合> * @return array */ public function getThread($tid, $fetchmode = self::FETCH_MAIN) { if (empty($tid)) return array(); return $this->_getThreadDao($fetchmode)->getThread($tid); } /** * 获取多个帖子信息 * * @param array $tids tid序列 * @param int $fetchmode 帖子资料 <必然为FETCH_*的一种或者组合> * @return array */ public function fetchThread($tids, $fetchmode = self::FETCH_MAIN) { if (empty($tids) || !is_array($tids)) return array(); return $this->_getThreadDao($fetchmode)->fetchThread($tids); } /** * 获取某个版块的帖子列表 (按最后回复排序) * * @param int $fid 版块id * @param int $limit 个数 * @param int $offset 起始偏移量 * @param int $fetchmode 帖子资料 <必然为FETCH_*的一种或者组合> * @return array */ public function getThreadByFid($fid, $limit, $offset = 0, $fetchmode = self::FETCH_MAIN) { return $this->_getThreadDao($fetchmode)->getThreadByFid($fid, $limit, $offset); } public function fetchThreadByTid($tids, $limit, $start, $fetchmode = self::FETCH_MAIN) { return $this->_getThreadDao($fetchmode)->fetchThreadByTid($tids, $limit, $start); } /** * 统计版块的帖子数/回复数 * * @param int $fid 版块fid * @return array */ public function countPosts($fid) { return $this->_getThreadDao()->countPosts($fid); } /** * 获取主题分类的帖子列表 */ public function getThreadByFidAndType($fid, $type, $limit, $start, $fetchmode = self::FETCH_MAIN) { return $this->_getThreadDao($fetchmode)->getThreadByFidAndType($fid, $type, $limit, $start); } public function countThreadByFidAndType($fid, $type) { return $this->_getThreadDao(self::FETCH_MAIN)->countThreadByFidAndType($fid, $type); } /** * 统计用户发帖数 * * @param int $uid * @return int */ public function countThreadByUid($uid) { if (empty($uid)) return 0; return $this->_getThreadDao(self::FETCH_MAIN)->countThreadByUid($uid); } /** * 获取用户的帖子 * * @param int $uid 用户id * @param int $limit 个数 * @param int $offset 起始偏移量 * @param int $fetchmode 帖子资料 <必然为FETCH_*的一种或者组合> * @return array */ public function getThreadByUid($uid, $limit = 0, $offset = 0, $fetchmode = self::FETCH_MAIN) { if (empty($uid)) return array(); return $this->_getThreadDao($fetchmode)->getThreadByUid($uid, $limit, $offset); } /** * 获取某个版块用户的帖子 * * @param int $fid 版块id * @param mixed $uids 用户id (int|array) * @param int $limit 个数 * @param int $offset 起始偏移量 * @param int $fetchmode 帖子资料 <必然为FETCH_*的一种或者组合> * @return array */ public function getThreadsByFidAndUids($fid, $uids, $limit = 0, $offset = 0, $fetchmode = self::FETCH_MAIN) { if (empty($fid) || empty($uids)) return array(); is_array($uids) || $uids = array($uids); return $this->_getThreadDao($fetchmode)->getThreadsByFidAndUids($fid, $uids, $limit, $offset); } /** * 增加帖子 * 注:本接口只提供数据层的相关操作,完整的帖子发布接口请参照 PwPost::execute() * * @param object $topicDm 帖子数据模型 * @return mixed */ public function addThread(PwTopicDm $topicDm) { if (($result = $topicDm->beforeAdd()) !== true) { return $result; } return $this->_getThreadDao(self::FETCH_ALL)->addThread($topicDm->getSetData()); } /** * 更新帖子 * * @param object $topicDm 帖子数据模型 * @param int $fetchmode 帖子资料 <必然为FETCH_*的一种或者组合> * @return mixed */ public function updateThread(PwTopicDm $topicDm, $fetchmode = self::FETCH_ALL) { if (($result = $topicDm->beforeUpdate()) !== true) { return $result; } return $this->_getThreadDao($fetchmode)->updateThread($topicDm->tid, $topicDm->getData(), $topicDm->getIncreaseData(), $topicDm->getBitData()); } /** * 批量更新帖子 * * @param array $tids 帖子id * @param object $topicDm 帖子数据模型 * @param int $fetchmode 帖子资料 <必然为FETCH_*的一种或者组合> * @return mixed */ public function batchUpdateThread($tids, PwTopicDm $topicDm, $fetchmode = self::FETCH_ALL) { if (empty($tids)) return false; if (($result = $topicDm->beforeUpdate()) !== true) { return $result; } return $this->_getThreadDao($fetchmode)->batchUpdateThread($tids, $topicDm->getData(), $topicDm->getIncreaseData(), $topicDm->getBitData()); } /** * 还原帖子disabled属性 * * @param array $tids * @return bool */ public function revertTopic($tids) { if (empty($tids) || !is_array($tids)) return false; return $this->_getThreadDao(self::FETCH_MAIN)->revertTopic($tids); } /** * 删除帖子 * 注:本接口只提供数据层的相关操作,完整的帖子删除接口请参照 PwDeleteTopic::execute() * * @param int $tid */ public function deleteThread($tid) { if (!$tid) return false; return $this->_getThreadDao(self::FETCH_ALL)->deleteThread($tid); } /** * 批量删除帖子 * 注:本接口只提供数据层的相关操作,完整的帖子删除接口请参照 PwDeleteTopic::execute() * * @param array $tids */ public function batchDeleteThread($tids) { if (empty($tids) || !is_array($tids)) return false; return $this->_getThreadDao(self::FETCH_ALL)->batchDeleteThread($tids); } /** * 统计帖子数(搜索) * * @param object $so * @return int */ public function countSearchThread(PwThreadSo $so) { return $this->_getThreadMergeDao()->countSearchThread($so->getData()); } /** * 搜索帖子 * * @param object $so * @return array */ public function searchThread(PwThreadSo $so, $limit = 20, $offset = 0, $fetchmode = self::FETCH_MAIN) { return $this->_getThreadMergeDao()->searchThread($fetchmode, $so->getData(), $so->getOrderby(), $limit, $offset); } /****************** 以上是主题接口 ******************\ \****************** 以下是回复接口 ******************/ /** * 获取一个回复 * * @param int $pid 回复id * @return array */ public function getPost($pid) { if (!$pid) return array(); return $this->_getPostDao()->getPost($pid); } /** * 获取多个回复 * * @param array $pids 回复ids * @return array */ public function fetchPost($pids) { if (empty($pids) || !is_array($pids)) return false; return $this->_getPostDao()->fetchPost($pids); } /** * 获取一个帖子的回复列表 * * @param int $tid 帖子id * @param int $limit * @param int $offset * @return array */ public function getPostByTid($tid, $limit = 20, $offset = 0, $asc = true) { if (empty($tid)) return array(); return $this->_getPostDao()->getPostByTid($tid, $limit, $offset, $asc); } /** * 统计用户的回复数 * * @param int $uid * @return int */ public function countPostByUid($uid) { if (empty($uid)) return 0; return $this->_getPostDao()->countPostByUid($uid); } /** * 获取用户的回复 * * @param int $uid 用户id * @param int $limit 个数 * @param int $offset 起始偏移量 * @return array */ public function getPostByUid($uid, $limit = 20, $offset = 0) { if (empty($uid)) return array(); return $this->_getPostDao()->getPostByUid($uid, $limit, $offset); } /** * 统计用户(A)在帖子(B)中的回复数 * * @param int $tid * @param int $uid * @return int */ public function countPostByTidAndUid($tid, $uid) { if (empty($tid) || empty($uid)) return 0; return $this->_getPostDao()->countPostByTidAndUid($tid, $uid); } /** * 统计帖子(A)中的ID小于回复(B)的回复个数 * * @param int $tid * @param int $pid * @return int */ public function countPostByTidUnderPid($tid, $pid) { if (empty($tid) || empty($pid)) return 0; return $this->_getPostDao()->countPostByTidUnderPid($tid, $pid); } /** * 获取用户(A)在帖子(B)中的回复 * * @param int $tid * @param int $uid * @param int $limit * @param int $offset * @param bool $asc * @return array */ public function getPostByTidAndUid($tid, $uid, $limit = 20, $offset = 0, $asc = true) { if (empty($tid) || empty($uid)) return array(); return $this->_getPostDao()->getPostByTidAndUid($tid, $uid, $limit, $offset, $asc); } /** * 统计回复数(搜索) * * @param object $so * @return int */ public function countSearchPost(PwPostSo $so) { return $this->_getPostDao()->countSearchPost($so->getData()); } /** * 搜索回复 * * @param object $so * @return array */ public function searchPost(PwPostSo $so, $limit = 20, $offset = 0) { return $this->_getPostDao()->searchPost($so->getData(), $so->getOrderby(), $limit, $offset); } /** * 增加一个回复 * * @param object $replyDm 回复数据模型 * @return array */ public function addPost(PwReplyDm $replyDm) { if (($result = $replyDm->beforeAdd()) !== true) { return $result; } return $this->_getPostDao()->addPost($replyDm->getData()); } /** * 更新回复 * * @param int $pid 回复id * @param object $replyDm 回复数据模型 * @return mixed */ public function updatePost(PwReplyDm $replyDm) { if (($result = $replyDm->beforeUpdate()) !== true) { return $result; } return $this->_getPostDao()->updatePost($replyDm->pid, $replyDm->getData(), $replyDm->getIncreaseData()); } /** * 批量更新帖子 * * @param array $pids 回复id * @param object $replyDm 帖子数据模型 * @return mixed */ public function batchUpdatePost($pids, PwReplyDm $replyDm) { if (empty($pids) || !is_array($pids)) return false; if (($result = $replyDm->beforeUpdate()) !== true) { return $result; } return $this->_getPostDao()->batchUpdatePost($pids, $replyDm->getData(), $replyDm->getIncreaseData()); } /** * 批量更新帖子 * * @param array $tids 帖子id * @param object $replyDm 帖子数据模型 * @return mixed */ public function batchUpdatePostByTid($tids, PwReplyDm $replyDm) { if (empty($tids)) return false; if (($result = $replyDm->beforeUpdate()) !== true) { return $result; } return $this->_getPostDao()->batchUpdatePostByTid($tids, $replyDm->getData(), $replyDm->getIncreaseData()); } /** * 还原帖子disabled属性 * * @param array $tids * @return bool */ public function revertPost($tids) { if (empty($tids) || !is_array($tids)) return false; return $this->_getPostDao()->revertPost($tids); } /** * 根据回复id批量删除回复 * * @param array $pids 回复id * @return bool */ public function batchDeletePost($pids) { if (empty($pids) || !is_array($pids)) return false; return $this->_getPostDao()->batchDeletePost($pids); } /** * 根据帖子id批量删除回复 * * @param array $tids 帖子id * @return bool */ public function batchDeletePostByTid($tids) { if (empty($tids) || !is_array($tids)) return false; return $this->_getPostDao()->batchDeletePostByTid($tids); } public function updateHits($tid, $hits) { return $this->_getThreadHitsDao()->update(intval($tid), intval($hits)); } public function syncHits() { return $this->_getThreadHitsDao()->syncHits(); } protected function _getDaoMap() { return array( self::FETCH_MAIN => 'forum.dao.PwThreadsDao', self::FETCH_CONTENT => 'forum.dao.PwThreadsContentDao' ); } protected function _getThreadDao($fetchmode = self::FETCH_MAIN) { return Wekit::loadDaoFromMap($fetchmode, $this->_getDaoMap(), 'PwThread'); } protected function _getThreadMergeDao() { // return Wekit::loadDao('forum.dao.PwThreadMergeDao'); return new PwThreadMergeDao(); } protected function _getPostDao() { return Wekit::loadDao('forum.dao.PwPostsDao'); } protected function _getThreadHitsDao() { return Wekit::loadDao('forum.dao.PwThreadsHitsDao'); } } /** * Enter description here ... * * @author jinlong.panjl * @copyright ©2003-2103 phpwind.com * @license http://www.phpwind.com * @version $Id$ * @package wind */ Wind::import('ADMIN:library.AdminBaseController'); Wind::import('SRV:forum.srv.operation.PwDeleteTopic'); Wind::import('SRV:forum.srv.operation.PwDeleteReply'); Wind::import('SRV:forum.srv.dataSource.PwFetchTopicByTid'); Wind::import('SRV:forum.srv.dataSource.PwFetchReplyByPid'); class ArticleController extends AdminBaseController { private $perpage = 20; public function run() { $fid = ''; $this->setOutput($this->_getFroumService()->getForumOption($fid), 'option_html'); $this->setTemplate('article_searchthread'); } public function threadadvancedAction() { $fid = ''; $this->setOutput($this->_getFroumService()->getForumOption($fid), 'option_html'); $this->setTemplate('article_searchthread_advanced'); } public function searchthreadAction() { // list($page, $perpage, $keyword, $created_username, $time_start, $time_end, $fid, $digest, $created_userid, $created_ip, $hits_start, $hits_end, $replies_start, $replies_end) = $this->getInput(array('page', 'perpage', 'keyword', 'created_username', 'time_start', 'time_end', 'fid', 'digest', 'created_userid', 'created_ip', 'hits_start', 'hits_end', 'replies_start', 'replies_end')); // if ($created_username) { // $user = $this->_getUserDs()->getUserByName($created_username); // if (!$user) $this->showError(array('USER:exists.not', array('{username}' => $created_username))); // if ($created_userid) { // ($created_userid != $user['uid']) && $this->showError('USER:username.notequal.uid'); // } // $created_userid = $user['uid']; // } list($keyword,$fid) = $this->getInput(array( 'keyword', 'fid')); // dm条件 Wind::import('SRV:forum.vo.PwThreadSo'); $dm = new PwThreadSo(); // $keyword && $dm->setKeywordOfTitleOrContent($keyword); $keyword && $dm->setKeywordOfTitle($keyword); if ($fid) { $forum = Wekit::load('forum.PwForum')->getForum($fid); if ($forum['type'] != 'category') { $dm->setFid($fid); } else { $srv = Wekit::load('forum.srv.PwForumService'); $fids = array(0); $forums = $srv->getForumsByLevel($fid, $srv->getForumMap()); foreach ($forums as $value) { $fids[] = $value['fid']; } $dm->setFid($fids); } } // $created_userid && $dm->setAuthorId($created_userid); // $time_start && $dm->setCreateTimeStart(Pw::str2time($time_start)); // $time_end && $dm->setCreateTimeEnd(Pw::str2time($time_end)); // $digest && $dm->setDigest($digest); // $hits_start && $dm->setHitsStart($hits_start); // $hits_end && $dm->setHitsEnd($hits_end); // $replies_start && $dm->setRepliesStart($replies_start); // $replies_end && $dm->setRepliesEnd($replies_end); // $created_ip && $dm->setCreatedIp($created_ip); $dm->setDisabled(0)->orderbyCreatedTime(false); $count = $this->_getThreadDs()->countSearchThread($dm); if ($count){ echo('[yes]'); }else{ echo('[no]'); } exit; // if ($count) { // $page = $page ? $page : 1; // $perpage = $perpage ? $perpage : $this->perpage; // list($start, $limit) = Pw::page2limit($page, $perpage); // $threads = $this->_getThreadDs()->searchThread($dm,$limit,$start); // } // $this->setOutput($count, 'count'); // $this->setOutput($page, 'page'); // $this->setOutput($perpage, 'perpage'); // $this->setOutput(array( // 'keyword' => $keyword, // 'created_username' => $created_username, // 'time_start' => $time_start, // 'time_end' => $time_end, // 'fid' => $fid, // 'digest' => $digest, // 'created_userid' => $created_userid, // 'created_ip' => $created_ip, // 'hits_start' => $hits_start, // 'hits_end' => $hits_end, // 'replies_start' => $replies_start, // 'replies_end' => $replies_end, // ), 'args'); // // $this->setOutput($this->_getFroumService()->getForumList($fid), 'forumList'); // $this->setOutput($this->_getFroumService()->getForumOption($fid), 'option_html'); // $this->setOutput($threads, 'threads'); } public function removeAction() { } public function deletethreadAction() { list($tids,$isDeductCredit) = $this->getInput(array('tids','isDeductCredit')); if (!is_array($tids) || !count($tids)) { $this->showError('operate.select'); } $service = new PwDeleteTopic(new PwFetchTopicByTid($tids), new PwUserBo($this->adminUser->getUid())); $service->setRecycle(true)->setIsDeductCredit((bool)$isDeductCredit)->execute(); $this->showMessage('operate.success'); } public function replylistAction() { $fid = ''; $this->setOutput($this->_getFroumService()->getForumOption($fid), 'option_html'); $this->setTemplate('article_searchreply'); } public function replyadvancedAction() { $fid = ''; $this->setOutput($this->_getFroumService()->getForumOption($fid), 'option_html'); $this->setTemplate('article_searchreply_advanced'); } public function searchreplyAction() { list($page, $perpage, $keyword, $fid, $created_username, $created_time_start, $created_time_end, $created_userid, $created_ip, $tid) = $this->getInput(array('page', 'perpage', 'keyword', 'fid', 'created_username', 'created_time_start', 'created_time_end', 'created_userid', 'created_ip', 'tid')); if ($created_username) { $user = $this->_getUserDs()->getUserByName($created_username); if (!$user) $this->showError('USER:username.empty'); if ($created_userid) { ($created_userid != $user['uid']) && $this->showError('USER:username.notequal.uid'); } $created_userid = $user['uid']; } // dm条件 Wind::import('SRV:forum.vo.PwPostSo'); $dm = new PwPostSo(); $dm->setDisabled(0)->orderbyCreatedTime(false); $keyword && $dm->setKeywordOfTitleOrContent($keyword); if ($fid) { $forum = Wekit::load('forum.PwForum')->getForum($fid); if ($forum['type'] != 'category') { $dm->setFid($fid); } else { $srv = Wekit::load('forum.srv.PwForumService'); $fids = array(0); $forums = $srv->getForumsByLevel($fid, $srv->getForumMap()); foreach ($forums as $value) { $fids[] = $value['fid']; } $dm->setFid($fids); } } $created_userid && $dm->setAuthorId($created_userid); $created_time_start && $dm->setCreateTimeStart(Pw::str2time($created_time_start)); $created_time_end && $dm->setCreateTimeEnd(Pw::str2time($created_time_end)); $tid && $dm->setTid($tid); $created_ip && $dm->setCreatedIp($created_ip); $count = $this->_getThreadDs()->countSearchPost($dm); if ($count) { $page = $page ? $page : 1; $perpage = $perpage ? $perpage : $this->perpage; list($start, $limit) = Pw::page2limit($page, $perpage); $posts = $this->_getThreadDs()->searchPost($dm,$limit,$start); } $this->setOutput($count, 'count'); $this->setOutput($page, 'page'); $this->setOutput($perpage, 'perpage'); $this->setOutput(array( 'keyword' => $keyword, 'created_username' => $created_username, 'created_time_start' => $created_time_start, 'created_time_end' => $created_time_end, 'fid' => $fid, 'created_userid' => $created_userid, 'created_ip' => $created_ip, 'tid' => $tid, ), 'args'); $this->setOutput($this->_getFroumService()->getForumList($fid), 'forumList'); $this->setOutput($this->_getFroumService()->getForumOption($fid), 'option_html'); $this->setOutput($posts, 'posts'); } /** * Enter description here ... * */ public function deletereplyAction() { list($pids,$isDeductCredit) = $this->getInput(array('pids','isDeductCredit')); if (!is_array($pids) || !count($pids)) { $this->showError('operate.select'); } $service = new PwDeleteReply(new PwFetchReplyByPid($pids), new PwUserBo($this->adminUser->getUid())); $service->setRecycle(true)->setIsDeductCredit((bool)$isDeductCredit)->execute(); $this->showMessage('operate.success'); } /** * Enter description here ... * * @return PwThread */ private function _getThreadDs(){ // return Wekit::load('forum.PwThread'); return new PwThread(); //zzcity } private function _getUserDs(){ return Wekit::load('user.PwUser'); } protected function _getFroumService() { return Wekit::load('forum.srv.PwForumService'); } } $components = array('router' => array()); Wekit::run('pwadmin', $components);