Merge branch 'master' of https://github.com/easysoft/zentaopms
Conflicts: www/js/my.full.js
This commit is contained in:
6
Makefile
6
Makefile
@@ -38,9 +38,9 @@ pms:
|
||||
# notify.zip.
|
||||
mkdir zentaopms/www/data/notify/
|
||||
# change mode.
|
||||
chmod 777 -R zentaopms/tmp/
|
||||
chmod 777 -R zentaopms/www/data
|
||||
chmod 777 -R zentaopms/config
|
||||
chmod -R 777 zentaopms/tmp/
|
||||
chmod -R 777 zentaopms/www/data
|
||||
chmod -R 777 zentaopms/config
|
||||
chmod 777 zentaopms/module
|
||||
chmod 777 zentaopms/www
|
||||
chmod a+rx zentaopms/bin/*
|
||||
|
||||
@@ -81,6 +81,10 @@ $config->file = new stdclass();
|
||||
$config->file->dangers = 'php,php3,php4,phtml,php5,jsp,py,rb,asp,asa,cer,cdx,aspl'; // Dangerous files.
|
||||
$config->file->maxSize = 1024 * 1024; // Max size.
|
||||
|
||||
/* IP white list settings.*/
|
||||
$config->ip = new stdclass();
|
||||
$config->ip->whiteList = '*';
|
||||
|
||||
/* View type settings. */
|
||||
$config->viewPrefix['mhtml'] = 'm.';
|
||||
|
||||
@@ -101,6 +105,12 @@ $config->slaveDB->encoding = 'UTF8';
|
||||
$config->slaveDB->strictMode = false;
|
||||
$config->slaveDB->checkCentOS= true;
|
||||
|
||||
/* Framework config. */
|
||||
$config->framework = new stdclass();
|
||||
$config->framework->jsWithPrefix = false;
|
||||
$config->framework->autoRepairTable = true;
|
||||
$config->framework->logDays = 14;
|
||||
|
||||
/* Include the custom config file. */
|
||||
$configRoot = dirname(__FILE__) . DIRECTORY_SEPARATOR;
|
||||
$myConfig = $configRoot . 'my.php';
|
||||
@@ -109,6 +119,7 @@ if(file_exists($myConfig)) include $myConfig;
|
||||
/* Set default table prefix. */
|
||||
if(!isset($config->db->prefix)) $config->db->prefix = 'zt_';
|
||||
|
||||
define('LANG_CREATED', false);
|
||||
/* Define the tables. */
|
||||
define('TABLE_COMPANY', '`' . $config->db->prefix . 'company`');
|
||||
define('TABLE_DEPT', '`' . $config->db->prefix . 'dept`');
|
||||
|
||||
25
db/update8.0.1.sql
Normal file
25
db/update8.0.1.sql
Normal file
@@ -0,0 +1,25 @@
|
||||
ALTER TABLE `zt_action` ADD INDEX `action` (`objectID`, `product`, `project`, `action`, `date`);
|
||||
ALTER TABLE `zt_branch` ADD INDEX `branch` (`product`);
|
||||
ALTER TABLE `zt_bug` ADD INDEX `bug` (`product`,`module`,`project`,`assignedTo`)
|
||||
ALTER TABLE `zt_build` ADD INDEX `build` (`product`, `project`);
|
||||
ALTER TABLE `zt_case` ADD INDEX `case` (`product`, `module`, `story`);
|
||||
ALTER TABLE `zt_cron` ADD INDEX `cron` (`lastTime`);
|
||||
ALTER TABLE `zt_dept` ADD INDEX `dept` (`parent`, `path`);
|
||||
ALTER TABLE `zt_doc` ADD INDEX `doc` (`product`, `project`);
|
||||
ALTER TABLE `zt_extension` ADD INDEX `extension` (`name`, `installedTime`), DROP INDEX `name`, DROP INDEX `addedTime`;
|
||||
ALTER TABLE `zt_file` ADD INDEX `file` (`objectType`, `objectID`), DROP INDEX `objectType`, DROP INDEX `objectID`;
|
||||
ALTER TABLE `zt_mailqueue` ADD INDEX `sendTime` (`sendTime`);
|
||||
ALTER TABLE `zt_module` ADD INDEX `module` (`root`, `type`, `path`), DROP INDEX `root`, DROP INDEX `type`;
|
||||
ALTER TABLE `zt_product` ADD INDEX `product` (`order`);
|
||||
ALTER TABLE `zt_productplan` ADD INDEX `plan` (`product`, `end`);
|
||||
ALTER TABLE `zt_project` ADD INDEX `project` (`parent`, `begin`, `end`, `status`, `order`), DROP INDEX `project`;
|
||||
ALTER TABLE `zt_release` ADD INDEX `release` (`build`);
|
||||
ALTER TABLE `zt_story` ADD INDEX `story` (`product`, `module`, `status`, `assignedTo`), DROP INDEX `status`, DROP INDEX `product`;
|
||||
ALTER TABLE `zt_storystage` ADD INDEX `story` (`story`);
|
||||
ALTER TABLE `zt_task` ADD INDEX `task` (`project`, `module`, `story`, `assignedTo`), DROP INDEX `project`, DROP INDEX `type`, DROP INDEX `status`;
|
||||
ALTER TABLE `zt_testresult` ADD INDEX `testresult` (`case`, `version`, `run`), DROP INDEX `run`, DROP INDEX `case`;
|
||||
ALTER TABLE `zt_testtask` ADD INDEX `testtask` (`build`);
|
||||
ALTER TABLE `zt_todo` ADD INDEX `todo` (`account`, `date`), DROP INDEX `user`;
|
||||
ALTER TABLE `zt_user` ADD INDEX `user` (`dept`, `email`, `commiter`), DROP INDEX `dept`;
|
||||
ALTER TABLE `zt_usercontact` ADD INDEX `user` (`account`);
|
||||
ALTER TABLE `zt_userquery` ADD INDEX `user` (`account`, `module`), DROP INDEX `account`, DROP INDEX `module`;
|
||||
@@ -11,7 +11,8 @@ CREATE TABLE IF NOT EXISTS `zt_action` (
|
||||
`comment` text NOT NULL,
|
||||
`extra` text NOT NULL,
|
||||
`read` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `action` (`objectID`,`product`,`project`,`action`,`date`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
-- DROP TABLE IF EXISTS `zt_branch`;
|
||||
@@ -20,7 +21,8 @@ CREATE TABLE IF NOT EXISTS `zt_branch` (
|
||||
`product` mediumint(8) unsigned NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`deleted` enum('0','1') NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `branch` (`product`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_bug`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_bug` (
|
||||
@@ -69,7 +71,8 @@ CREATE TABLE IF NOT EXISTS `zt_bug` (
|
||||
`lastEditedBy` varchar(30) NOT NULL default '',
|
||||
`lastEditedDate` datetime NOT NULL,
|
||||
`deleted` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `bug` (`product`,`module`,`project`,`assignedTo`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_build`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_build` (
|
||||
@@ -86,7 +89,8 @@ CREATE TABLE IF NOT EXISTS `zt_build` (
|
||||
`builder` char(30) NOT NULL default '',
|
||||
`desc` text NOT NULL,
|
||||
`deleted` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `build` (`product`,`project`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_burn`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_burn` (
|
||||
@@ -130,7 +134,8 @@ CREATE TABLE IF NOT EXISTS `zt_case` (
|
||||
`lastRunner` varchar(30) NOT NULL,
|
||||
`lastRunDate` datetime NOT NULL,
|
||||
`lastRunResult` char(30) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `case` (`product`,`module`,`story`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_casestep`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_casestep` (
|
||||
@@ -182,7 +187,8 @@ CREATE TABLE IF NOT EXISTS `zt_cron` (
|
||||
`buildin` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`status` varchar(20) NOT NULL,
|
||||
`lastTime` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `cron` (`lastTime`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_lang`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_lang` (
|
||||
@@ -207,7 +213,8 @@ CREATE TABLE IF NOT EXISTS `zt_dept` (
|
||||
`position` char(30) NOT NULL default '',
|
||||
`function` char(255) NOT NULL default '',
|
||||
`manager` char(30) NOT NULL default '',
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `dept` (`parent`,`path`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_doc`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_doc` (
|
||||
@@ -228,7 +235,8 @@ CREATE TABLE IF NOT EXISTS `zt_doc` (
|
||||
`editedBy` varchar(30) NOT NULL,
|
||||
`editedDate` datetime NOT NULL,
|
||||
`deleted` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `doc` (`product`,`project`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_doclib`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_doclib` (
|
||||
@@ -272,8 +280,7 @@ CREATE TABLE IF NOT EXISTS `zt_extension` (
|
||||
`status` varchar(20) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `code` (`code`),
|
||||
KEY `name` (`name`),
|
||||
KEY `addedTime` (`installedTime`)
|
||||
KEY `extension` (`name`,`installedTime`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_file`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_file` (
|
||||
@@ -289,7 +296,8 @@ CREATE TABLE IF NOT EXISTS `zt_file` (
|
||||
`downloads` mediumint(8) unsigned NOT NULL default '0',
|
||||
`extra` varchar(255) NOT NULL,
|
||||
`deleted` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `file` (`objectType`,`objectID`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_group`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_group` (
|
||||
@@ -315,7 +323,8 @@ CREATE TABLE IF NOT EXISTS `zt_history` (
|
||||
`old` text NOT NULL,
|
||||
`new` text NOT NULL,
|
||||
`diff` mediumtext NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `action` (`action`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_mailqueue`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_mailqueue` (
|
||||
@@ -329,7 +338,8 @@ CREATE TABLE IF NOT EXISTS `zt_mailqueue` (
|
||||
`sendTime` datetime NOT NULL,
|
||||
`status` varchar(10) NOT NULL DEFAULT 'wait',
|
||||
`failReason` text NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `sendTime` (`sendTime`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_module`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_module` (
|
||||
@@ -343,7 +353,8 @@ CREATE TABLE IF NOT EXISTS `zt_module` (
|
||||
`order` smallint(5) unsigned NOT NULL default '0',
|
||||
`type` char(30) NOT NULL,
|
||||
`owner` varchar(30) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `module` (`root`,`type`,`path`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_product`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_product` (
|
||||
@@ -363,7 +374,8 @@ CREATE TABLE IF NOT EXISTS `zt_product` (
|
||||
`createdVersion` varchar(20) NOT NULL,
|
||||
`order` mediumint(8) unsigned NOT NULL,
|
||||
`deleted` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `product` (`order`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_productplan`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_productplan` (
|
||||
@@ -375,7 +387,8 @@ CREATE TABLE IF NOT EXISTS `zt_productplan` (
|
||||
`begin` date NOT NULL,
|
||||
`end` date NOT NULL,
|
||||
`deleted` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `plan` (`product`,`end`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_project`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_project` (
|
||||
@@ -410,7 +423,7 @@ CREATE TABLE IF NOT EXISTS `zt_project` (
|
||||
`order` mediumint(8) unsigned NOT NULL,
|
||||
`deleted` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `project` (`type`,`parent`,`begin`,`end`,`status`,`statge`,`pri`)
|
||||
KEY `project` (`parent`,`begin`,`end`,`status`,`order`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_projectproduct`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_projectproduct` (
|
||||
@@ -441,7 +454,8 @@ CREATE TABLE IF NOT EXISTS `zt_release` (
|
||||
`desc` text NOT NULL,
|
||||
`status` varchar(20) NOT NULL default 'normal',
|
||||
`deleted` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `release` (`build`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_story`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_story` (
|
||||
@@ -478,8 +492,7 @@ CREATE TABLE IF NOT EXISTS `zt_story` (
|
||||
`version` smallint(6) NOT NULL default '1',
|
||||
`deleted` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `product` (`product`,`module`,`type`,`pri`),
|
||||
KEY `status` (`status`)
|
||||
KEY `story` (`product`,`module`,`status`,`assignedTo`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_storyspec`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_storyspec` (
|
||||
@@ -494,7 +507,8 @@ CREATE TABLE IF NOT EXISTS `zt_storyspec` (
|
||||
CREATE TABLE IF NOT EXISTS `zt_storystage` (
|
||||
`story` mediumint(8) unsigned NOT NULL,
|
||||
`branch` mediumint(8) unsigned NOT NULL,
|
||||
`stage` varchar(50) NOT NULL
|
||||
`stage` varchar(50) NOT NULL,
|
||||
KEY `story` (`story`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_task`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_task` (
|
||||
@@ -530,8 +544,8 @@ CREATE TABLE IF NOT EXISTS `zt_task` (
|
||||
`lastEditedBy` varchar(30) NOT NULL,
|
||||
`lastEditedDate` datetime NOT NULL,
|
||||
`deleted` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `type` (`type`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `task` (`project`,`module`,`story`,`assignedTo`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_taskestimate`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_taskestimate` (
|
||||
@@ -566,8 +580,7 @@ CREATE TABLE IF NOT EXISTS `zt_testresult` (
|
||||
`lastRunner` varchar(30) NOT NULL,
|
||||
`date` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `run` (`run`),
|
||||
KEY `case` (`case`,`version`)
|
||||
KEY `testresult` (`case`,`version`, `run`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_testrun`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_testrun` (
|
||||
@@ -598,7 +611,8 @@ CREATE TABLE IF NOT EXISTS `zt_testtask` (
|
||||
`report` text NOT NULL,
|
||||
`status` enum('blocked','doing','wait','done') NOT NULL DEFAULT 'wait',
|
||||
`deleted` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `testtask` (`build`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_todo`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_todo` (
|
||||
@@ -615,7 +629,7 @@ CREATE TABLE IF NOT EXISTS `zt_todo` (
|
||||
`status` enum('wait','doing','done') NOT NULL DEFAULT 'wait',
|
||||
`private` tinyint(1) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `user` (`account`)
|
||||
KEY `todo` (`account`,`date`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_user`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_user` (
|
||||
@@ -650,7 +664,7 @@ CREATE TABLE IF NOT EXISTS `zt_user` (
|
||||
`deleted` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `account` (`account`),
|
||||
KEY `dept` (`dept`)
|
||||
KEY `user` (`dept`,`email`,`commiter`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_usercontact`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_usercontact` (
|
||||
@@ -658,7 +672,8 @@ CREATE TABLE IF NOT EXISTS `zt_usercontact` (
|
||||
`account` char(30) NOT NULL,
|
||||
`listName` varchar(60) NOT NULL,
|
||||
`userList` text NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `user` (`account`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_usergroup`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_usergroup` (
|
||||
@@ -675,8 +690,7 @@ CREATE TABLE IF NOT EXISTS `zt_userquery` (
|
||||
`form` text NOT NULL,
|
||||
`sql` text NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `account` (`account`),
|
||||
KEY `module` (`module`)
|
||||
KEY `user` (`account`, `module`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_usertpl`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_usertpl` (
|
||||
|
||||
@@ -1 +1 @@
|
||||
升级,请参考 http://www.zentao.net/article-view-78960.html
|
||||
升级,请参考 http://www.zentao.net/book/zentaopmshelp/41.html
|
||||
|
||||
360
framework/control.class.php
Executable file → Normal file
360
framework/control.class.php
Executable file → Normal file
@@ -1,23 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* ZenTaoPHP的control类。
|
||||
* The control class file of ZenTaoPHP framework.
|
||||
*
|
||||
* The author disclaims copyright to this source code. In place of
|
||||
* a legal notice, here is a blessing:
|
||||
*
|
||||
*
|
||||
* May you do good and not evil.
|
||||
* May you find forgiveness for yourself and forgive others.
|
||||
* May you share freely, never taking more than you give.
|
||||
*/
|
||||
|
||||
/**
|
||||
* control基类,所有模块的control类都派生于它。
|
||||
* The base class of control.
|
||||
*
|
||||
*
|
||||
* @package framework
|
||||
*/
|
||||
class control
|
||||
{
|
||||
/**
|
||||
* 全局对象 $app。
|
||||
* The global $app object.
|
||||
*
|
||||
* @var object
|
||||
@@ -26,6 +29,16 @@ class control
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* 应用名称 $appName
|
||||
* The global $appName.
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $appName;
|
||||
|
||||
/**
|
||||
* 全局对象 $config。
|
||||
* The global $config object.
|
||||
*
|
||||
* @var object
|
||||
@@ -34,6 +47,7 @@ class control
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* 全局对象 $lang。
|
||||
* The global $lang object.
|
||||
*
|
||||
* @var object
|
||||
@@ -42,6 +56,7 @@ class control
|
||||
protected $lang;
|
||||
|
||||
/**
|
||||
* 全局对象 $dbh,数据库连接句柄。
|
||||
* The global $dbh object, the database connection handler.
|
||||
*
|
||||
* @var object
|
||||
@@ -50,6 +65,7 @@ class control
|
||||
protected $dbh;
|
||||
|
||||
/**
|
||||
* $dao对象,封装SQL语句,方便数据库访问和更新。
|
||||
* The $dao object, used to access or update database.
|
||||
*
|
||||
* @var object
|
||||
@@ -58,6 +74,7 @@ class control
|
||||
public $dao;
|
||||
|
||||
/**
|
||||
* $post对象,将$_POST数组改为对象,方便调用。
|
||||
* The $post object, used to access the $_POST var.
|
||||
*
|
||||
* @var ojbect
|
||||
@@ -66,6 +83,7 @@ class control
|
||||
public $post;
|
||||
|
||||
/**
|
||||
* $get对象,将$_GET数组改为对象,方便调用。
|
||||
* The $get object, used to access the $_GET var.
|
||||
*
|
||||
* @var ojbect
|
||||
@@ -74,6 +92,7 @@ class control
|
||||
public $get;
|
||||
|
||||
/**
|
||||
* $session对象,将$_SESSION数组改为对象,方便调用。
|
||||
* The $session object, used to access the $_SESSION var.
|
||||
*
|
||||
* @var ojbect
|
||||
@@ -82,6 +101,7 @@ class control
|
||||
public $session;
|
||||
|
||||
/**
|
||||
* $server对象,将$_SERVER数组改为对象,方便调用。
|
||||
* The $server object, used to access the $_SERVER var.
|
||||
*
|
||||
* @var ojbect
|
||||
@@ -90,6 +110,7 @@ class control
|
||||
public $server;
|
||||
|
||||
/**
|
||||
* $cookie对象,将$_COOKIE数组改为对象,方便调用。
|
||||
* The $cookie object, used to access the $_COOKIE var.
|
||||
*
|
||||
* @var ojbect
|
||||
@@ -98,6 +119,7 @@ class control
|
||||
public $cookie;
|
||||
|
||||
/**
|
||||
* $global对象,将$_COOKIE数组改为对象,方便调用。
|
||||
* The $global object, used to access the $_GLOBAL var.
|
||||
*
|
||||
* @var ojbect
|
||||
@@ -106,6 +128,7 @@ class control
|
||||
public $global;
|
||||
|
||||
/**
|
||||
* 当前模块的名称。
|
||||
* The name of current module.
|
||||
*
|
||||
* @var string
|
||||
@@ -114,6 +137,7 @@ class control
|
||||
protected $moduleName;
|
||||
|
||||
/**
|
||||
* $view用于存放从control传到view视图的数据。
|
||||
* The vars assigned to the view page.
|
||||
*
|
||||
* @var object
|
||||
@@ -122,6 +146,7 @@ class control
|
||||
public $view;
|
||||
|
||||
/**
|
||||
* 视图的类型,比如html json。
|
||||
* The type of the view, such html, json.
|
||||
*
|
||||
* @var string
|
||||
@@ -130,6 +155,7 @@ class control
|
||||
private $viewType;
|
||||
|
||||
/**
|
||||
* 输出到浏览器的内容。
|
||||
* The content to display.
|
||||
*
|
||||
* @var string
|
||||
@@ -146,47 +172,80 @@ class control
|
||||
public $viewPrefix;
|
||||
|
||||
/**
|
||||
* The device of visiting client.
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $device;
|
||||
|
||||
/**
|
||||
* 构造方法。
|
||||
*
|
||||
* 1. 将全局变量设为control类的成员变量,方便control的派生类调用;
|
||||
* 2. 设置当前模块,读取该模块的model类;
|
||||
* 3. 初始化$view视图类。
|
||||
*
|
||||
* The construct function.
|
||||
*
|
||||
* 1. global the global vars, refer them by the class member such as $this->app.
|
||||
* 2. set the pathes of current module, and load it's mode class.
|
||||
* 2. set the pathes of current module, and load it's model class.
|
||||
* 3. auto assign the $lang and $config to the view.
|
||||
*
|
||||
* @param string $moduleName
|
||||
* @param string $methodName
|
||||
* @param string $appName
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($moduleName = '', $methodName = '')
|
||||
public function __construct($moduleName = '', $methodName = '', $appName = '')
|
||||
{
|
||||
/* Global the globals, and refer them to the class member. */
|
||||
global $app, $config, $lang, $dbh;
|
||||
/*
|
||||
* 将全局变量设为control类的成员变量,方便control的派生类调用。
|
||||
* Global the globals, and refer them to the class member.
|
||||
**/
|
||||
global $app, $config, $lang, $dbh, $common;
|
||||
$this->app = $app;
|
||||
$this->config = $config;
|
||||
$this->lang = $lang;
|
||||
$this->dbh = $dbh;
|
||||
$this->viewType = $this->app->getViewType();
|
||||
$this->appName = $appName ? $appName : $this->app->getAppName();
|
||||
|
||||
/* Load the model file auto. */
|
||||
/*
|
||||
* 设置当前模块,读取该模块的model类。
|
||||
* Load the model file auto.
|
||||
**/
|
||||
$this->setModuleName($moduleName);
|
||||
$this->setMethodName($methodName);
|
||||
$this->loadModel();
|
||||
$this->loadModel($this->moduleName, $appName);
|
||||
$this->setViewPrefix();
|
||||
|
||||
/* Init the view vars. */
|
||||
/*
|
||||
* 初始化$view视图类。
|
||||
* Init the view vars.
|
||||
**/
|
||||
$this->view = new stdclass();
|
||||
$this->view->app = $app;
|
||||
$this->view->lang = $lang;
|
||||
$this->view->config = $config;
|
||||
$this->view->title = '';
|
||||
$this->view->app = $app;
|
||||
$this->view->lang = $lang;
|
||||
$this->view->config = $config;
|
||||
$this->view->common = $common;
|
||||
$this->view->title = '';
|
||||
|
||||
/* Set super vars. */
|
||||
/*
|
||||
* 设置超级变量,从$app引用过来。
|
||||
* Set super vars.
|
||||
**/
|
||||
$this->setSuperVars();
|
||||
}
|
||||
|
||||
//-------------------- Model related methods --------------------//
|
||||
//-------------------- Model相关方法(Model related methods) --------------------//
|
||||
|
||||
/* Set the module name.
|
||||
/*
|
||||
* 设置模块名。
|
||||
* Set the module name.
|
||||
*
|
||||
* @param string $moduleName The module name, if empty, get it from $app.
|
||||
* @param string $moduleName 模块名,如果为空,则从$app中获取 The module name, if empty, get it from $app.
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
@@ -195,9 +254,10 @@ class control
|
||||
$this->moduleName = $moduleName ? strtolower($moduleName) : $this->app->getModuleName();
|
||||
}
|
||||
|
||||
/* Set the method name.
|
||||
/* Set the method name.
|
||||
* 设置方法名。
|
||||
*
|
||||
* @param string $methodName The method name, if empty, get it from $app.
|
||||
* @param string $methodName 方法名,如果为空,则从$app中获取 The method name, if empty, get it from $app.
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
@@ -207,35 +267,46 @@ class control
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载指定模块的model文件。
|
||||
* Load the model file of one module.
|
||||
*
|
||||
* @param string $methodName The method name, if empty, use current module's name.
|
||||
* @param string $moduleName 模块名,如果为空,使用当前模块 The module name, if empty, use current module's name.
|
||||
* @param string $appName The app name, if empty, use current app's name.
|
||||
* @access public
|
||||
* @return object|bool If no model file, return false. Else return the model object.
|
||||
* @return object|bool 如果没有model文件,返回false,否则返回model对象。 If no model file, return false. Else return the model object.
|
||||
*/
|
||||
public function loadModel($moduleName = '')
|
||||
public function loadModel($moduleName = '', $appName = '')
|
||||
{
|
||||
if(empty($moduleName)) $moduleName = $this->moduleName;
|
||||
$modelFile = helper::setModelFile($moduleName);
|
||||
if(empty($appName)) $appName = $this->appName;
|
||||
$modelFile = helper::setModelFile($moduleName, $appName);
|
||||
|
||||
/* If no model file, try load config. */
|
||||
/*
|
||||
* 如果没有model文件,尝试加载config配置信息。
|
||||
* If no model file, try load config.
|
||||
*/
|
||||
if(!helper::import($modelFile))
|
||||
{
|
||||
$this->app->loadConfig($moduleName, false);
|
||||
$this->app->loadLang($moduleName);
|
||||
$this->app->loadConfig($moduleName, $appName, false);
|
||||
$this->app->loadLang($moduleName, $appName);
|
||||
$this->dao = new dao();
|
||||
return false;
|
||||
}
|
||||
|
||||
$modelClass = class_exists('ext' . $moduleName. 'model') ? 'ext' . $moduleName . 'model' : $moduleName . 'model';
|
||||
if(!class_exists($modelClass)) $this->app->triggerError(" The model $modelClass not found", __FILE__, __LINE__, $exit = true);
|
||||
$modelClass = class_exists('ext' . $appName . $moduleName. 'model') ? 'ext' . $appName . $moduleName . 'model' : $appName . $moduleName . 'model';
|
||||
if(!class_exists($modelClass))
|
||||
{
|
||||
$modelClass = class_exists('ext' . $moduleName. 'model') ? 'ext' . $moduleName . 'model' : $moduleName . 'model';
|
||||
if(!class_exists($modelClass)) $this->app->triggerError(" The model $modelClass not found", __FILE__, __LINE__, $exit = true);
|
||||
}
|
||||
|
||||
$this->$moduleName = new $modelClass();
|
||||
$this->$moduleName = new $modelClass($appName);
|
||||
$this->dao = $this->$moduleName->dao;
|
||||
return $this->$moduleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置超级全局变量,$app已经设置过了,直接引用。
|
||||
* Set the super vars.
|
||||
*
|
||||
* @access protected
|
||||
@@ -252,6 +323,7 @@ class control
|
||||
}
|
||||
|
||||
/**
|
||||
* 为客户端是PC还是移动设备,设置视图文件前缀名。
|
||||
* Set the prefix of view file for mobile or PC.
|
||||
*
|
||||
* @access public
|
||||
@@ -263,9 +335,22 @@ class control
|
||||
if(isset($this->config->viewPrefix[$this->viewType])) $this->viewPrefix = $this->config->viewPrefix[$this->viewType];
|
||||
}
|
||||
|
||||
//-------------------- View related methods --------------------//
|
||||
|
||||
/**
|
||||
* 设置客户端的设备类型
|
||||
* Set current device of visit website.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function setCurrentDevice()
|
||||
{
|
||||
$this->app->setCurrentDevice();
|
||||
$this->device = $this->app->device;
|
||||
}
|
||||
//-------------------- 视图相关方法(View related methods) --------------------//
|
||||
|
||||
/**
|
||||
* 设置视图文件,可以获取其他模块的视图文件。
|
||||
* Set the view file, thus can use fetch other module's page.
|
||||
*
|
||||
* @param string $moduleName module name
|
||||
@@ -273,30 +358,42 @@ class control
|
||||
* @access private
|
||||
* @return string the view file
|
||||
*/
|
||||
private function setViewFile($moduleName, $methodName)
|
||||
public function setViewFile($moduleName, $methodName)
|
||||
{
|
||||
$moduleName = strtolower(trim($moduleName));
|
||||
$methodName = strtolower(trim($methodName));
|
||||
|
||||
$modulePath = $this->app->getModulePath($moduleName);
|
||||
$viewExtPath = $this->app->getModuleExtPath($moduleName, 'view');
|
||||
$modulePath = $this->app->getModulePath($this->appName, $moduleName);
|
||||
$viewExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'view');
|
||||
|
||||
/* Set infix for view file in mobile or pc. */
|
||||
$viewType = $this->viewType;
|
||||
if(isset($this->config->viewPrefix[$this->viewType])) $viewType = 'html';
|
||||
|
||||
/* The main view file, extension view file and hook file. */
|
||||
/*
|
||||
* 主视图文件,扩展视图文件和钩子文件。
|
||||
* The main view file, extension view file and hook file.
|
||||
**/
|
||||
$mainViewFile = $modulePath . 'view' . DS . $this->viewPrefix . $methodName . '.' . $viewType . '.php';
|
||||
$extViewFile = $viewExtPath . $this->viewPrefix . $methodName . ".{$viewType}.php";
|
||||
$extHookFiles = glob($viewExtPath . $this->viewPrefix . $methodName . ".*.{$viewType}.hook.php");
|
||||
|
||||
$viewFile = file_exists($extViewFile) ? $extViewFile : $mainViewFile;
|
||||
/* Extension view file. */
|
||||
$commonExtViewFile = $viewExtPath['common'] . $this->viewPrefix . $methodName . ".{$viewType}.php";
|
||||
$siteExtViewFile = empty($viewExtPath['site']) ? '' : $viewExtPath['site'] . $this->viewPrefix . $methodName . ".{$viewType}.php";
|
||||
|
||||
$viewFile = file_exists($commonExtViewFile) ? $commonExtViewFile : $mainViewFile;
|
||||
$viewFile = (!empty($siteExtViewFile) and file_exists($siteExtViewFile)) ? $siteExtViewFile : $viewFile;
|
||||
if(!is_file($viewFile)) $this->app->triggerError("the view file $viewFile not found", __FILE__, __LINE__, $exit = true);
|
||||
|
||||
/* Extension hook file. */
|
||||
$commonExtHookFiles = glob($viewExtPath['common'] . $this->viewPrefix . $methodName . ".*.{$viewType}.hook.php");
|
||||
$siteExtHookFiles = empty($viewExtPath['site']) ? '' : glob($viewExtPath['site'] . $this->viewPrefix . $methodName . ".*.{$viewType}.hook.php");
|
||||
$extHookFiles = array_merge((array) $commonExtHookFiles, (array) $siteExtHookFiles);
|
||||
if(!empty($extHookFiles)) return array('viewFile' => $viewFile, 'hookFiles' => $extHookFiles);
|
||||
return $viewFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取视图的扩展文件,在ext/view/目录下
|
||||
* Get the extension file of an view.
|
||||
*
|
||||
* @param string $viewFile
|
||||
@@ -305,7 +402,19 @@ class control
|
||||
*/
|
||||
public function getExtViewFile($viewFile)
|
||||
{
|
||||
$extPath = dirname(dirname(realpath($viewFile))) . '/ext/view/';
|
||||
if($this->config->site->code)
|
||||
{
|
||||
$extPath = dirname(dirname(realpath($viewFile))) . "/ext/_{$this->config->site->code}/view";
|
||||
$extViewFile = $extPath . basename($viewFile);
|
||||
|
||||
if(file_exists($extViewFile))
|
||||
{
|
||||
helper::cd($extPath);
|
||||
return $extViewFile;
|
||||
}
|
||||
}
|
||||
|
||||
$extPath = dirname(dirname(realpath($viewFile))) . '/ext/view/';
|
||||
$extViewFile = $extPath . basename($viewFile);
|
||||
if(file_exists($extViewFile))
|
||||
{
|
||||
@@ -316,6 +425,7 @@ class control
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取方法的css内容,common.css + 该方法的css。
|
||||
* Get css code for a method.
|
||||
*
|
||||
* @param string $moduleName
|
||||
@@ -327,37 +437,50 @@ class control
|
||||
{
|
||||
$moduleName = strtolower(trim($moduleName));
|
||||
$methodName = strtolower(trim($methodName));
|
||||
$modulePath = $this->app->getModulePath($moduleName);
|
||||
$cssMethodExt = $this->app->getModuleExtPath($moduleName, 'css') . $methodName . DS;
|
||||
$cssCommonExt = $this->app->getModuleExtPath($moduleName, 'css') . 'common' . DS;
|
||||
|
||||
$modulePath = $this->app->getModulePath($this->appName, $moduleName);
|
||||
$cssExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'css') ;
|
||||
$cssMethodExt = $cssExtPath['common'] . $methodName . DS;
|
||||
$cssCommonExt = $cssExtPath['common'] . 'common' . DS;
|
||||
|
||||
$css = '';
|
||||
$mainCssFile = $modulePath . 'css' . DS . $this->viewPrefix . 'common.css';
|
||||
$methodCssFile = $modulePath . 'css' . DS . $this->viewPrefix . $methodName . '.css';
|
||||
if(file_exists($mainCssFile)) $css .= file_get_contents($mainCssFile);
|
||||
if(is_file($methodCssFile)) $css .= file_get_contents($methodCssFile);
|
||||
if(file_exists($mainCssFile)) $css .= file_get_contents($mainCssFile);
|
||||
if(is_file($methodCssFile)) $css .= file_get_contents($methodCssFile);
|
||||
|
||||
$cssExtFiles = glob($cssCommonExt . $this->viewPrefix . '*.css');
|
||||
if(is_array($cssExtFiles))
|
||||
if(!empty($cssExtFiles) and is_array($cssExtFiles))
|
||||
{
|
||||
foreach($cssExtFiles as $cssFile)
|
||||
{
|
||||
$css .= file_get_contents($cssFile);
|
||||
}
|
||||
foreach($cssExtFiles as $cssFile) $css .= file_get_contents($cssFile);
|
||||
}
|
||||
|
||||
$cssExtFiles = glob($cssMethodExt . $this->viewPrefix . '*.css');
|
||||
if(is_array($cssExtFiles))
|
||||
if(!empty($cssExtFiles) and is_array($cssExtFiles))
|
||||
{
|
||||
foreach($cssExtFiles as $cssFile)
|
||||
foreach($cssExtFiles as $cssFile) $css .= file_get_contents($cssFile);
|
||||
}
|
||||
if(!empty($cssExtPath['site']))
|
||||
{
|
||||
$cssMethodExt = $cssExtPath['site'] . $methodName . DS;
|
||||
$cssCommonExt = $cssExtPath['site'] . 'common' . DS;
|
||||
$cssExtFiles = glob($cssCommonExt . $this->viewPrefix . '*.css');
|
||||
if(!empty($cssExtFiles) and is_array($cssExtFiles))
|
||||
{
|
||||
$css .= file_get_contents($cssFile);
|
||||
foreach($cssExtFiles as $cssFile) $css .= file_get_contents($cssFile);
|
||||
}
|
||||
|
||||
$cssExtFiles = glob($cssMethodExt . $this->viewPrefix . '*.css');
|
||||
if(!empty($cssExtFiles) and is_array($cssExtFiles))
|
||||
{
|
||||
foreach($cssExtFiles as $cssFile) $css .= file_get_contents($cssFile);
|
||||
}
|
||||
}
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取方法的js,common.js + 该方法的js。
|
||||
* Get js code for a method.
|
||||
*
|
||||
* @param string $moduleName
|
||||
@@ -369,9 +492,11 @@ class control
|
||||
{
|
||||
$moduleName = strtolower(trim($moduleName));
|
||||
$methodName = strtolower(trim($methodName));
|
||||
$modulePath = $this->app->getModulePath($moduleName);
|
||||
$jsMethodExt = $this->app->getModuleExtPath($moduleName, 'js') . $methodName . DS;
|
||||
$jsCommonExt = $this->app->getModuleExtPath($moduleName, 'js') . 'common' . DS;
|
||||
|
||||
$modulePath = $this->app->getModulePath($this->appName, $moduleName);
|
||||
$jsExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'js');
|
||||
$jsMethodExt = $jsExtPath['common'] . $methodName . DS;
|
||||
$jsCommonExt = $jsExtPath['common'] . 'common' . DS;
|
||||
|
||||
$js = '';
|
||||
$mainJsFile = $modulePath . 'js' . DS . $this->viewPrefix . 'common.js';
|
||||
@@ -380,26 +505,39 @@ class control
|
||||
if(is_file($methodJsFile)) $js .= file_get_contents($methodJsFile);
|
||||
|
||||
$jsExtFiles = glob($jsCommonExt . $this->viewPrefix . '*.js');
|
||||
if(is_array($jsExtFiles))
|
||||
if(!empty($jsExtFiles) and is_array($jsExtFiles))
|
||||
{
|
||||
foreach($jsExtFiles as $jsFile)
|
||||
{
|
||||
$js .= file_get_contents($jsFile);
|
||||
}
|
||||
foreach($jsExtFiles as $jsFile) $js .= file_get_contents($jsFile);
|
||||
}
|
||||
|
||||
$jsExtFiles = glob($jsMethodExt . $this->viewPrefix . '*.js');
|
||||
if(is_array($jsExtFiles))
|
||||
if(!empty($jsExtFiles) and is_array($jsExtFiles))
|
||||
{
|
||||
foreach($jsExtFiles as $jsFile)
|
||||
foreach($jsExtFiles as $jsFile) $js .= file_get_contents($jsFile);
|
||||
}
|
||||
|
||||
if(!empty($jsExtPath['site']))
|
||||
{
|
||||
$jsMethodExt = $jsExtPath['site'] . $methodName . DS;
|
||||
$jsCommonExt = $jsExtPath['site'] . 'common' . DS;
|
||||
|
||||
$jsExtFiles = glob($jsCommonExt . $this->viewPrefix . '*.js');
|
||||
if(!empty($jsExtFiles) and is_array($jsExtFiles))
|
||||
{
|
||||
$js .= file_get_contents($jsFile);
|
||||
foreach($jsExtFiles as $jsFile) $js .= file_get_contents($jsFile);
|
||||
}
|
||||
|
||||
$jsExtFiles = glob($jsMethodExt . $this->viewPrefix . '*.js');
|
||||
if(!empty($jsExtFiles) and is_array($jsExtFiles))
|
||||
{
|
||||
foreach($jsExtFiles as $jsFile) $js .= file_get_contents($jsFile);
|
||||
}
|
||||
}
|
||||
return $js;
|
||||
}
|
||||
|
||||
/**
|
||||
* 向$view传递一个变量。
|
||||
* Assign one var to the view vars.
|
||||
*
|
||||
* @param string $name the name.
|
||||
@@ -413,8 +551,9 @@ class control
|
||||
}
|
||||
|
||||
/**
|
||||
* 将之前打算输出的内容清空。
|
||||
* Clear the output.
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -424,6 +563,7 @@ class control
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据请求的视图类型,生成输出内容。
|
||||
* Parse view file.
|
||||
*
|
||||
* @param string $moduleName module name, if empty, use current module.
|
||||
@@ -448,6 +588,7 @@ class control
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求为json格式的处理逻辑。
|
||||
* Parse json format.
|
||||
*
|
||||
* @param string $moduleName module name
|
||||
@@ -471,6 +612,7 @@ class control
|
||||
}
|
||||
|
||||
/**
|
||||
* 其他请求格式的处理逻辑,输出视图文件的内容。
|
||||
* Parse default html format.
|
||||
*
|
||||
* @param string $moduleName module name
|
||||
@@ -481,13 +623,14 @@ class control
|
||||
private function parseDefault($moduleName, $methodName)
|
||||
{
|
||||
/* Set the view file. */
|
||||
$viewFile = $this->setViewFile($moduleName, $methodName);
|
||||
if(is_array($viewFile)) extract($viewFile);
|
||||
$results = $this->setViewFile($moduleName, $methodName);
|
||||
$viewFile = $results;
|
||||
if(is_array($results)) extract($results);
|
||||
|
||||
/* Get css and js. */
|
||||
$css = $this->getCSS($moduleName, $methodName);
|
||||
$js = $this->getJS($moduleName, $methodName);
|
||||
if($css) $this->view->pageCss = $css;
|
||||
if($css) $this->view->pageCSS = $css;
|
||||
if($js) $this->view->pageJS = $js;
|
||||
|
||||
/* Change the dir to the view file to keep the relative pathes work. */
|
||||
@@ -497,7 +640,7 @@ class control
|
||||
extract((array)$this->view);
|
||||
ob_start();
|
||||
include $viewFile;
|
||||
if(isset($hookFiles)) foreach($hookFiles as $hookFile) include $hookFile;
|
||||
if(isset($hookFiles)) foreach($hookFiles as $hookFile) if(file_exists($hookFile)) include $hookFile;
|
||||
$this->output .= ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
@@ -506,8 +649,10 @@ class control
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取一个方法的输出内容,这样我们可以在一个方法里获取其他模块方法的内容。
|
||||
* 如果模块名为空,则调用该模块、该方法;如果设置了模块名,调用指定模块指定方法。
|
||||
*
|
||||
* Get the output of one module's one method as a string, thus in one module's method, can fetch other module's content.
|
||||
*
|
||||
* If the module name is empty, then use the current module and method. If set, use the user defined module and method.
|
||||
*
|
||||
* @param string $moduleName module name.
|
||||
@@ -516,42 +661,58 @@ class control
|
||||
* @access public
|
||||
* @return string the parsed html.
|
||||
*/
|
||||
public function fetch($moduleName = '', $methodName = '', $params = array())
|
||||
public function fetch($moduleName = '', $methodName = '', $params = array(), $appName = '')
|
||||
{
|
||||
if($moduleName == '') $moduleName = $this->moduleName;
|
||||
if($methodName == '') $methodName = $this->methodName;
|
||||
if($appName == '') $appName = $this->appName;
|
||||
if($moduleName == $this->moduleName and $methodName == $this->methodName)
|
||||
{
|
||||
$this->parse($moduleName, $methodName);
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
/* Set the pathes and files to included. */
|
||||
$modulePath = $this->app->getModulePath($moduleName);
|
||||
/*
|
||||
* 设置引用的文件和路径。
|
||||
* Set the pathes and files to included.
|
||||
**/
|
||||
$modulePath = $this->app->getModulePath($appName, $moduleName);
|
||||
$moduleControlFile = $modulePath . 'control.php';
|
||||
$actionExtFile = $this->app->getModuleExtPath($moduleName, 'control') . strtolower($methodName) . '.php';
|
||||
$file2Included = file_exists($actionExtFile) ? $actionExtFile : $moduleControlFile;
|
||||
$actionExtPath = $this->app->getModuleExtPath($appName, $moduleName, 'control');
|
||||
|
||||
$commonActionExtFile = $actionExtPath['common'] . strtolower($methodName) . '.php';
|
||||
$file2Included = file_exists($commonActionExtFile) ? $commonActionExtFile : $moduleControlFile;
|
||||
if(!empty($actionExtPath['site']))
|
||||
{
|
||||
$siteActionExtFile = $actionExtPath['site'] . strtolower($methodName) . '.php';
|
||||
$file2Included = file_exists($siteActionExtFile) ? $siteActionExtFile : $file2Included;
|
||||
}
|
||||
|
||||
/* 加载控制器文件。 */
|
||||
/* Load the control file. */
|
||||
if(!is_file($file2Included)) $this->app->triggerError("The control file $file2Included not found", __FILE__, __LINE__, $exit = true);
|
||||
$currentPWD = getcwd();
|
||||
chdir(dirname($file2Included));
|
||||
if($moduleName != $this->moduleName) helper::import($file2Included);
|
||||
|
||||
|
||||
/* 设置调用的类名。 */
|
||||
/* Set the name of the class to be called. */
|
||||
$className = class_exists("my$moduleName") ? "my$moduleName" : $moduleName;
|
||||
if(!class_exists($className)) $this->app->triggerError(" The class $className not found", __FILE__, __LINE__, $exit = true);
|
||||
|
||||
/* 解析参数,创建模块control对象。 */
|
||||
/* Parse the params, create the $module control object. */
|
||||
if(!is_array($params)) parse_str($params, $params);
|
||||
$module = new $className($moduleName, $methodName);
|
||||
$module = new $className($moduleName, $methodName, $appName);
|
||||
|
||||
/* 调用对应方法,使用ob方法获取输出内容。 */
|
||||
/* Call the method and use ob function to get the output. */
|
||||
ob_start();
|
||||
call_user_func_array(array($module, $methodName), $params);
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
/* 返回内容。 */
|
||||
/* Return the content. */
|
||||
unset($module);
|
||||
chdir($currentPWD);
|
||||
@@ -559,8 +720,9 @@ class control
|
||||
}
|
||||
|
||||
/**
|
||||
* 向浏览器输出内容。
|
||||
* Print the content of the view.
|
||||
*
|
||||
*
|
||||
* @param string $moduleName module name
|
||||
* @param string $methodName method name
|
||||
* @access public
|
||||
@@ -571,24 +733,54 @@ class control
|
||||
if(empty($this->output)) $this->parse($moduleName, $methodName);
|
||||
echo $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接输出data数据,通常用于ajax请求中。
|
||||
* Send data directly, for ajax requests.
|
||||
*
|
||||
*
|
||||
* @param misc $data
|
||||
* @param string $type
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function send($data, $type = 'json')
|
||||
{
|
||||
if($type == 'json') echo json_encode($data);
|
||||
{
|
||||
$data = (array) $data;
|
||||
if($type == 'json')
|
||||
{
|
||||
if(!helper::isAjaxRequest())
|
||||
{
|
||||
if(isset($data['result']) and $data['result'] == 'success')
|
||||
{
|
||||
if(!empty($data['message'])) echo js::alert($data['message']);
|
||||
$locate = isset($data['locate']) ? $data['locate'] : (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '');
|
||||
if(!empty($locate)) die(js::locate($locate));
|
||||
die(isset($data['message']) ? $data['message'] : 'success');
|
||||
}
|
||||
|
||||
if(isset($data['result']) and $data['result'] == 'fail')
|
||||
{
|
||||
if(!empty($data['message']))
|
||||
{
|
||||
$message = json_decode(json_encode((array)$data['message']));
|
||||
foreach((array)$message as $item => $errors)
|
||||
{
|
||||
$message->$item = implode(',', $errors);
|
||||
}
|
||||
echo js::alert(strip_tags(implode(" ", (array) $message)));
|
||||
die(js::locate('back'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($data);
|
||||
}
|
||||
die(helper::removeUTF8Bom(ob_get_clean()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个模块方法的链接。
|
||||
* Create a link to one method of one module.
|
||||
*
|
||||
*
|
||||
* @param string $moduleName module name
|
||||
* @param string $methodName method name
|
||||
* @param string|array $vars the params passed, can be array(key=>value) or key1=value1&key2=value2
|
||||
@@ -603,6 +795,7 @@ class control
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建当前模块的一个方法链接。
|
||||
* Create a link to the inner method of current module.
|
||||
*
|
||||
* @param string $methodName method name
|
||||
@@ -617,6 +810,7 @@ class control
|
||||
}
|
||||
|
||||
/**
|
||||
* 重定向到另一个页面。
|
||||
* Location to another page.
|
||||
*
|
||||
* @param string $url the target url.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
97
framework/model.class.php
Executable file → Normal file
97
framework/model.class.php
Executable file → Normal file
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* ZenTaoPHP的model类。
|
||||
* The model class file of ZenTaoPHP framework.
|
||||
*
|
||||
* The author disclaims copyright to this source code. In place of
|
||||
@@ -11,6 +12,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* model基类。
|
||||
* The base class of model.
|
||||
*
|
||||
* @package framework
|
||||
@@ -18,6 +20,7 @@
|
||||
class model
|
||||
{
|
||||
/**
|
||||
* 全局对象$app。
|
||||
* The global $app object.
|
||||
*
|
||||
* @var object
|
||||
@@ -26,6 +29,16 @@ class model
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* 应用名称$appName。
|
||||
* The global appName.
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $appName;
|
||||
|
||||
/**
|
||||
* 全局对象$config。
|
||||
* The global $config object.
|
||||
*
|
||||
* @var object
|
||||
@@ -34,6 +47,7 @@ class model
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* 全局对象$lang。
|
||||
* The global $lang object.
|
||||
*
|
||||
* @var object
|
||||
@@ -42,6 +56,7 @@ class model
|
||||
protected $lang;
|
||||
|
||||
/**
|
||||
* 全局对象$dbh,数据库连接句柄。
|
||||
* The global $dbh object, the database connection handler.
|
||||
*
|
||||
* @var object
|
||||
@@ -50,6 +65,7 @@ class model
|
||||
protected $dbh;
|
||||
|
||||
/**
|
||||
* $dao对象,用于访问或者更新数据库。
|
||||
* The $dao object, used to access or update database.
|
||||
*
|
||||
* @var object
|
||||
@@ -58,6 +74,7 @@ class model
|
||||
public $dao;
|
||||
|
||||
/**
|
||||
* $post对象,用于访问$_POST变量。
|
||||
* The $post object, used to access the $_POST var.
|
||||
*
|
||||
* @var ojbect
|
||||
@@ -66,6 +83,7 @@ class model
|
||||
public $post;
|
||||
|
||||
/**
|
||||
* $get对象,用于访问$_GET变量。
|
||||
* The $get object, used to access the $_GET var.
|
||||
*
|
||||
* @var ojbect
|
||||
@@ -74,7 +92,8 @@ class model
|
||||
public $get;
|
||||
|
||||
/**
|
||||
* The $sesion object, used to access the $_SESSION var.
|
||||
* $session对象,用于访问$_SESSION变量。
|
||||
* The $session object, used to access the $_SESSION var.
|
||||
*
|
||||
* @var ojbect
|
||||
* @access public
|
||||
@@ -82,6 +101,7 @@ class model
|
||||
public $session;
|
||||
|
||||
/**
|
||||
* $server对象,用于访问$_SERVER变量。
|
||||
* The $server object, used to access the $_SERVER var.
|
||||
*
|
||||
* @var ojbect
|
||||
@@ -90,6 +110,7 @@ class model
|
||||
public $server;
|
||||
|
||||
/**
|
||||
* $cookie对象,用于访问$_COOKIE变量。
|
||||
* The $cookie object, used to access the $_COOKIE var.
|
||||
*
|
||||
* @var ojbect
|
||||
@@ -98,6 +119,7 @@ class model
|
||||
public $cookie;
|
||||
|
||||
/**
|
||||
* $global对象,用于访问$_GLOBAL变量。
|
||||
* The $global object, used to access the $_GLOBAL var.
|
||||
*
|
||||
* @var ojbect
|
||||
@@ -106,37 +128,48 @@ class model
|
||||
public $global;
|
||||
|
||||
/**
|
||||
* 构造方法。
|
||||
* 1. 将全局变量设为model类的成员变量,方便model的派生类调用;
|
||||
* 2. 设置$config, $lang, $dbh, $dao。
|
||||
*
|
||||
* The construct function.
|
||||
*
|
||||
* 1. global the global vars, refer them by the class member such as $this->app.
|
||||
* 2. set the pathes, config, lang of current module
|
||||
*
|
||||
*
|
||||
* @param string $appName
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct($appName = '')
|
||||
{
|
||||
global $app, $config, $lang, $dbh;
|
||||
$this->app = $app;
|
||||
$this->config = $config;
|
||||
$this->lang = $lang;
|
||||
$this->dbh = $dbh;
|
||||
$this->app = $app;
|
||||
$this->config = $config;
|
||||
$this->lang = $lang;
|
||||
$this->dbh = $dbh;
|
||||
$this->appName = empty($appName) ? $this->app->getAppName() : $appName;
|
||||
|
||||
$moduleName = $this->getModuleName();
|
||||
$this->app->loadLang($moduleName, $exit = false);
|
||||
$this->app->loadConfig($moduleName, $exit = false);
|
||||
|
||||
$this->app->loadLang($moduleName, $this->appName);
|
||||
$this->app->loadConfig($moduleName, $this->appName, $exitIfNone = false);
|
||||
|
||||
$this->loadDAO();
|
||||
$this->setSuperVars();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取该model的模块名,而不是用户请求的模块名。
|
||||
*
|
||||
* 这个方法通过去掉该model类名的'ext'和'model'字符串,来获取当前模块名。
|
||||
* 不要使用$app->getModuleName(),因为其返回的是用户请求的模块名。
|
||||
* 另一个model可以通过loadModel()加载进来,与请求的模块名不一致。
|
||||
*
|
||||
* Get the module name of this model. Not the module user visiting.
|
||||
*
|
||||
* This method replace the 'ext' and 'model' string from the model class name, thus get the module name.
|
||||
* Not useing $app->getModuleName() because it return the module user is visiting. But one module can be
|
||||
* loaded by loadModel() so we must get the module name of thie model.
|
||||
*
|
||||
* Not using $app->getModuleName() because it return the module user is visiting. But one module can be
|
||||
* loaded by loadModel() so we must get the module name of this model.
|
||||
*
|
||||
* @access protected
|
||||
* @return string the module name.
|
||||
*/
|
||||
@@ -150,6 +183,7 @@ class model
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置全局超级变量。
|
||||
* Set the super vars.
|
||||
*
|
||||
* @access protected
|
||||
@@ -166,26 +200,35 @@ class model
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the model of one module. After loaded, can use $this->modulename to visit the model object.
|
||||
* 加载一个模块的model。加载完成后,使用$this->$moduleName来访问这个model对象。
|
||||
* 比如:loadModel('user')引入user模块的model实例对象,可以通过$this->user来访问它。
|
||||
*
|
||||
* Load the model of one module. After loaded, can use $this->$moduleName to visit the model object.
|
||||
*
|
||||
* @param string $moduleName
|
||||
* @access public
|
||||
* @return object|bool the model object or false if model file not exists.
|
||||
*/
|
||||
public function loadModel($moduleName)
|
||||
public function loadModel($moduleName, $appName = '')
|
||||
{
|
||||
if(empty($moduleName)) return false;
|
||||
$modelFile = helper::setModelFile($moduleName);
|
||||
if(empty($appName)) $appName = $this->appName;
|
||||
$modelFile = helper::setModelFile($moduleName, $appName);
|
||||
|
||||
if(!helper::import($modelFile)) return false;
|
||||
$modelClass = class_exists('ext' . $moduleName. 'model') ? 'ext' . $moduleName . 'model' : $moduleName . 'model';
|
||||
if(!class_exists($modelClass)) $this->app->triggerError(" The model $modelClass not found", __FILE__, __LINE__, $exit = true);
|
||||
$modelClass = class_exists('ext' . $appName . $moduleName. 'model') ? 'ext' . $appName . $moduleName . 'model' : $appName . $moduleName . 'model';
|
||||
if(!class_exists($modelClass))
|
||||
{
|
||||
$modelClass = class_exists('ext' . $moduleName. 'model') ? 'ext' . $moduleName . 'model' : $moduleName . 'model';
|
||||
if(!class_exists($modelClass)) $this->app->triggerError(" The model $modelClass not found", __FILE__, __LINE__, $exit = true);
|
||||
}
|
||||
|
||||
$this->$moduleName = new $modelClass();
|
||||
$this->$moduleName = new $modelClass($appName);
|
||||
return $this->$moduleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载model的class扩展。
|
||||
* Load extension class of a model. Saved to $moduleName/ext/model/class/$extensionName.class.php.
|
||||
*
|
||||
* @param string $extensionName
|
||||
@@ -200,10 +243,12 @@ class model
|
||||
/* Set extenson name and extension file. */
|
||||
$extensionName = strtolower($extensionName);
|
||||
$moduleName = $moduleName ? $moduleName : $this->getModuleName();
|
||||
$extensionFile = $this->app->getModuleExtPath($moduleName, 'model') . 'class/' . $extensionName . '.class.php';
|
||||
$moduleExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'model');
|
||||
if(!empty($moduleExtPath['site']))$extensionFile = $moduleExtPath['site'] . 'class/' . $extensionName . '.class.php';
|
||||
if(!isset($extensionFile) or !file_exists($extensionFile)) $extensionFile = $moduleExtPath['common'] . 'class/' . $extensionName . '.class.php';
|
||||
|
||||
/* Try to import parent model file auto and then import the extension file. */
|
||||
if(!class_exists($moduleName . 'Model')) helper::import($this->app->getModulePath($moduleName) . 'model.php');
|
||||
if(!class_exists($moduleName . 'Model')) helper::import($this->app->getModulePath($this->appName, $moduleName) . 'model.php');
|
||||
if(!helper::import($extensionFile)) return false;
|
||||
|
||||
/* Set the extension class name. */
|
||||
@@ -217,9 +262,8 @@ class model
|
||||
return $extensionObject;
|
||||
}
|
||||
|
||||
//-------------------- DAO related method s--------------------//
|
||||
|
||||
/**
|
||||
* 加载DAO。
|
||||
* Load DAO.
|
||||
*
|
||||
* @access private
|
||||
@@ -231,6 +275,7 @@ class model
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除记录
|
||||
* Delete one record.
|
||||
*
|
||||
* @param string $table the table name
|
||||
@@ -241,7 +286,7 @@ class model
|
||||
public function delete($table, $id)
|
||||
{
|
||||
$this->dao->update($table)->set('deleted')->eq(1)->where('id')->eq($id)->exec();
|
||||
$object = str_replace($this->config->db->prefix, '', $table);
|
||||
$object = ltrim(strstr(trim($table, '`'), '_'), '_');
|
||||
$this->loadModel('action')->create($object, $id, 'deleted', '', $extra = ACTIONMODEL::CAN_UNDELETED);
|
||||
}
|
||||
}
|
||||
}
|
||||
94
framework/myrouter.class.php
Executable file
94
framework/myrouter.class.php
Executable file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
include 'router.class.php';
|
||||
class myrouter extends router
|
||||
{
|
||||
public function loadCommon()
|
||||
{
|
||||
$this->setModuleName('common');
|
||||
$commonModelFile = helper::setModelFile('common');
|
||||
if(file_exists($commonModelFile))
|
||||
{
|
||||
helper::import($commonModelFile);
|
||||
if(class_exists('extcommonModel'))
|
||||
{
|
||||
$commonClass = 'class common extends extcommonModel{}';
|
||||
eval($commonClass);
|
||||
return new extcommonModel();
|
||||
}
|
||||
elseif(class_exists('commonModel'))
|
||||
{
|
||||
$commonClass = 'class common extends commonModel{}';
|
||||
eval($commonClass);
|
||||
return new commonModel();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function loadLang($moduleName, $appName = '')
|
||||
{
|
||||
$modulePath = $this->getModulePath($appName, $moduleName);
|
||||
$mainLangFile = $modulePath . 'lang' . DS . $this->clientLang . '.php';
|
||||
$extLangPath = $this->getModuleExtPath($appName, $moduleName, 'lang');
|
||||
$commonExtLangFiles = helper::ls($extLangPath['common'] . $this->clientLang, '.php');
|
||||
$siteExtLangFiles = helper::ls($extLangPath['site'] . $this->clientLang, '.php');
|
||||
$extLangFiles = array_merge($commonExtLangFiles, $siteExtLangFiles);
|
||||
|
||||
/* Set the files to includ. */
|
||||
if(!is_file($mainLangFile))
|
||||
{
|
||||
if(empty($extLangFiles)) return false; // also no extension file.
|
||||
$langFiles = $extLangFiles;
|
||||
}
|
||||
else
|
||||
{
|
||||
$langFiles = array_merge(array($mainLangFile), $extLangFiles);
|
||||
}
|
||||
|
||||
global $lang;
|
||||
if(!is_object($lang)) $lang = new language();
|
||||
|
||||
/* Set productCommon and projectCommon for flow. */
|
||||
if($moduleName == 'common')
|
||||
{
|
||||
$productProject = false;
|
||||
if($this->dbh and !empty($this->config->db->name)) $productProject = $this->dbh->query('SELECT value FROM' . TABLE_CONFIG . "WHERE `owner`='system' AND `module`='custom' AND `key`='productproject'")->fetch();
|
||||
|
||||
$productCommon = $projectCommon = 0;
|
||||
if($productProject)
|
||||
{
|
||||
$productProject = $productProject->value;
|
||||
list($productCommon, $projectCommon) = explode('_', $productProject);
|
||||
}
|
||||
$lang->productCommon = isset($this->config->productCommonList[$this->clientLang][(int)$productCommon]) ? $this->config->productCommonList[$this->clientLang][(int)$productCommon] : $this->config->productCommonList['zh-cn'][0];
|
||||
$lang->projectCommon = isset($this->config->projectCommonList[$this->clientLang][(int)$projectCommon]) ? $this->config->projectCommonList[$this->clientLang][(int)$projectCommon] : $this->config->projectCommonList['zh-cn'][0];
|
||||
}
|
||||
|
||||
static $loadedLangs = array();
|
||||
foreach($langFiles as $langFile)
|
||||
{
|
||||
if(in_array($langFile, $loadedLangs)) continue;
|
||||
include $langFile;
|
||||
$loadedLangs[] = $langFile;
|
||||
}
|
||||
|
||||
/* Merge from the db lang. */
|
||||
if($moduleName != 'common' and isset($lang->db->custom[$moduleName]))
|
||||
{
|
||||
foreach($lang->db->custom[$moduleName] as $section => $fields)
|
||||
{
|
||||
foreach($fields as $key => $value)
|
||||
{
|
||||
unset($lang->{$moduleName}->{$section}[$key]);
|
||||
$lang->{$moduleName}->{$section}[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->lang = $lang;
|
||||
return $lang;
|
||||
}
|
||||
}
|
||||
969
framework/router.class.php
Executable file → Normal file
969
framework/router.class.php
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
522
lib/dao/dao.class.php
Executable file → Normal file
522
lib/dao/dao.class.php
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
283
lib/filter/filter.class.php
Executable file → Normal file
283
lib/filter/filter.class.php
Executable file → Normal file
@@ -1,28 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* ZenTaoPHP的验证和过滤类。
|
||||
* The validater and fixer class file of ZenTaoPHP framework.
|
||||
*
|
||||
* The author disclaims copyright to this source code. In place of
|
||||
* a legal notice, here is a blessing:
|
||||
*
|
||||
*
|
||||
* May you do good and not evil.
|
||||
* May you find forgiveness for yourself and forgive others.
|
||||
* May you share freely, never taking more than you give.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The valida class, checking datas by rules.
|
||||
*
|
||||
* validater类,检查数据是否符合规则。
|
||||
* The validater class, checking data by rules.
|
||||
*
|
||||
* @package framework
|
||||
*/
|
||||
class validater
|
||||
{
|
||||
/**
|
||||
* 最大参数个数。
|
||||
* The max count of args.
|
||||
*/
|
||||
const MAX_ARGS = 3;
|
||||
|
||||
/**
|
||||
* 是否是Bool类型。
|
||||
* Bool checking.
|
||||
*
|
||||
* @param bool $var
|
||||
@@ -36,6 +40,7 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是Int类型。
|
||||
* Int checking.
|
||||
*
|
||||
* @param int $var
|
||||
@@ -46,12 +51,13 @@ class validater
|
||||
public static function checkInt($var)
|
||||
{
|
||||
$args = func_get_args();
|
||||
if($var != 0) $var = ltrim($var, 0); // Remove the left 0, filter don't think 00 is an int.
|
||||
if($var != 0) $var = ltrim($var, 0); // 去掉变量左边的0,00不是Int类型
|
||||
// Remove the left 0, filter don't think 00 is an int.
|
||||
|
||||
/* Min is setted. */
|
||||
/* 如果设置了最小的整数。 Min is setted. */
|
||||
if(isset($args[1]))
|
||||
{
|
||||
/* And Max is setted. */
|
||||
/* 如果最大的整数也设置了。 And Max is setted. */
|
||||
if(isset($args[2]))
|
||||
{
|
||||
$options = array('options' => array('min_range' => $args[1], 'max_range' => $args[2]));
|
||||
@@ -70,6 +76,21 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查不是Int类型。
|
||||
* Not int checking.
|
||||
*
|
||||
* @param int $var
|
||||
* @static
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkNotInt($var)
|
||||
{
|
||||
return !self::checkInt($var);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查Float类型。
|
||||
* Float checking.
|
||||
*
|
||||
* @param float $var
|
||||
@@ -80,10 +101,11 @@ class validater
|
||||
*/
|
||||
public static function checkFloat($var, $decimal = '.')
|
||||
{
|
||||
return filter_var($var, FILTER_VALIDATE_FLOAT, array('options' => array('decimail' => $decimal)));
|
||||
return filter_var($var, FILTER_VALIDATE_FLOAT, array('options' => array('decimal' => $decimal)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查Email。
|
||||
* Email checking.
|
||||
*
|
||||
* @param string $var
|
||||
@@ -97,8 +119,52 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* URL checking.
|
||||
* 检查电话或手机号码
|
||||
* Check phone number.
|
||||
*
|
||||
* @param string $var
|
||||
* @static
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public static function checkPhone($var)
|
||||
{
|
||||
return (validater::checkTel($var) or validater::checkMobile($var));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查电话号码
|
||||
* Check tel number.
|
||||
*
|
||||
* @param int $var
|
||||
* @static
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public static function checkTel($var)
|
||||
{
|
||||
return preg_match("/^([0-9]{3,4}-)?[0-9]{7,8}$/", $var);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查手机号码
|
||||
* Check mobile number.
|
||||
*
|
||||
* @param string $var
|
||||
* @static
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public static function checkMobile($var)
|
||||
{
|
||||
return preg_match("/^1[3-5,8]{1}[0-9]{9}$/", $var);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查网址。
|
||||
* 该规则不支持中文字符的网址。
|
||||
*
|
||||
* URL checking.
|
||||
* The check rule of filter don't support chinese.
|
||||
*
|
||||
* @param string $var
|
||||
@@ -112,6 +178,23 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查域名,不支持中文。
|
||||
* Domain checking.
|
||||
*
|
||||
* The check rule of filter don't support chinese.
|
||||
*
|
||||
* @param string $var
|
||||
* @static
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkDomain($var)
|
||||
{
|
||||
return preg_match('/^([a-z0-9-]+\.)+[a-z]{2,15}$/', $var);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查IP地址。
|
||||
* IP checking.
|
||||
*
|
||||
* @param ip $var
|
||||
@@ -132,6 +215,7 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期检查。注意,2009-09-31是一个合法日期,系统会将它转换为2009-10-01。
|
||||
* Date checking. Note: 2009-09-31 will be an valid date, because strtotime auto fixed it to 10-01.
|
||||
*
|
||||
* @param date $date
|
||||
@@ -148,6 +232,7 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查正则表达式。
|
||||
* REG checking.
|
||||
*
|
||||
* @param string $var
|
||||
@@ -160,8 +245,9 @@ class validater
|
||||
{
|
||||
return filter_var($var, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => $reg)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查长度。
|
||||
* Length checking.
|
||||
*
|
||||
* @param string $var
|
||||
@@ -178,6 +264,7 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查不为空。
|
||||
* Not empty checking.
|
||||
*
|
||||
* @param mixed $var
|
||||
@@ -191,6 +278,7 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查为空。
|
||||
* Empty checking.
|
||||
*
|
||||
* @param mixed $var
|
||||
@@ -204,6 +292,7 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户名。
|
||||
* Account checking.
|
||||
*
|
||||
* @param string $var
|
||||
@@ -219,6 +308,21 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查Code。
|
||||
* Check code.
|
||||
*
|
||||
* @param string $var
|
||||
* @static
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkCode($var)
|
||||
{
|
||||
return self::checkREG($var, '|^[A-Za-z0-9]+$|');
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查验证码。
|
||||
* Check captcha.
|
||||
*
|
||||
* @param mixed $var
|
||||
@@ -233,6 +337,7 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否等于给定的值。
|
||||
* Must equal a value.
|
||||
*
|
||||
* @param mixed $var
|
||||
@@ -247,6 +352,22 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查不等于给定的值
|
||||
* Must not equal a value.
|
||||
*
|
||||
* @param mixed $var
|
||||
* @param mixed $value
|
||||
* @static
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkNotEqual($var, $value)
|
||||
{
|
||||
return $var != $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查大于给定的值。
|
||||
* Must greater than a value.
|
||||
*
|
||||
* @param mixed $var
|
||||
@@ -261,6 +382,7 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查小于给定的值
|
||||
* Must less than a value.
|
||||
*
|
||||
* @param mixed $var
|
||||
@@ -275,6 +397,7 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查大于等于给定的值
|
||||
* Must greater than a value or equal a value.
|
||||
*
|
||||
* @param mixed $var
|
||||
@@ -289,6 +412,7 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查小于等于给定的值
|
||||
* Must less than a value or equal a value.
|
||||
*
|
||||
* @param mixed $var
|
||||
@@ -303,6 +427,7 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否在给定的列表里面。
|
||||
* Must in value list.
|
||||
*
|
||||
* @param mixed $var
|
||||
@@ -316,8 +441,9 @@ class validater
|
||||
if(!is_array($value)) $value = explode(',', $value);
|
||||
return in_array($var, $value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查文件名。
|
||||
* Check file name.
|
||||
*
|
||||
* @param string $var
|
||||
@@ -331,6 +457,31 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查敏感词。
|
||||
* Check sensitive words.
|
||||
*
|
||||
* @param object $vars
|
||||
* @param array $dicts
|
||||
* @static
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public static function checkSensitive($vars, $dicts)
|
||||
{
|
||||
foreach($vars as $var)
|
||||
{
|
||||
if(!$var) continue;
|
||||
foreach($dicts as $dict)
|
||||
{
|
||||
if(strpos($var, $dict) === false) continue;
|
||||
if(strpos($var, $dict) !== false) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用一个方法进行检查。
|
||||
* Call a function to check it.
|
||||
*
|
||||
* @param mixed $var
|
||||
@@ -346,6 +497,7 @@ class validater
|
||||
}
|
||||
|
||||
/**
|
||||
* fixer类,处理数据。
|
||||
* fixer class, to fix data types.
|
||||
*
|
||||
* @package framework
|
||||
@@ -353,6 +505,7 @@ class validater
|
||||
class fixer
|
||||
{
|
||||
/**
|
||||
* 处理的数据。
|
||||
* The data to be fixed.
|
||||
*
|
||||
* @var ojbect
|
||||
@@ -360,8 +513,17 @@ class fixer
|
||||
*/
|
||||
private $data;
|
||||
|
||||
private $stripedFields = array();
|
||||
/**
|
||||
* 跳过处理的字段。
|
||||
* The fields to striped.
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
private $stripedFields = array();
|
||||
|
||||
/**
|
||||
* 构造方法,将超级全局变量转换为对象。
|
||||
* The construction function, according the scope, convert it to object.
|
||||
*
|
||||
* @param string $scope the scope of the var, should be post|get|server|session|cookie|env
|
||||
@@ -370,36 +532,37 @@ class fixer
|
||||
*/
|
||||
private function __construct($scope)
|
||||
{
|
||||
switch($scope)
|
||||
{
|
||||
case 'post':
|
||||
$this->data = (object)$_POST;
|
||||
break;
|
||||
case 'server':
|
||||
$this->data = (object)$_SERVER;
|
||||
break;
|
||||
case 'get':
|
||||
$this->data = (object)$_GET;
|
||||
break;
|
||||
case 'session':
|
||||
$this->data = (object)$_SESSION;
|
||||
break;
|
||||
case 'cookie':
|
||||
$this->data = (object)$_COOKIE;
|
||||
break;
|
||||
case 'env':
|
||||
$this->data = (object)$_ENV;
|
||||
break;
|
||||
case 'file':
|
||||
$this->data = (object)$_FILES;
|
||||
break;
|
||||
switch($scope)
|
||||
{
|
||||
case 'post':
|
||||
$this->data = (object)$_POST;
|
||||
break;
|
||||
case 'server':
|
||||
$this->data = (object)$_SERVER;
|
||||
break;
|
||||
case 'get':
|
||||
$this->data = (object)$_GET;
|
||||
break;
|
||||
case 'session':
|
||||
$this->data = (object)$_SESSION;
|
||||
break;
|
||||
case 'cookie':
|
||||
$this->data = (object)$_COOKIE;
|
||||
break;
|
||||
case 'env':
|
||||
$this->data = (object)$_ENV;
|
||||
break;
|
||||
case 'file':
|
||||
$this->data = (object)$_FILES;
|
||||
break;
|
||||
|
||||
default:
|
||||
die('scope not supported, should be post|get|server|session|cookie|env');
|
||||
}
|
||||
default:
|
||||
die('scope not supported, should be post|get|server|session|cookie|env');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 工厂方法。
|
||||
* The factory function.
|
||||
*
|
||||
* @param string $scope
|
||||
@@ -412,6 +575,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理Email。
|
||||
* Email fix.
|
||||
*
|
||||
* @param string $fieldName
|
||||
@@ -426,7 +590,8 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* urlenocde.
|
||||
* url编码。
|
||||
* urlencode.
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @access public
|
||||
@@ -444,6 +609,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理网址。
|
||||
* Clean the url.
|
||||
*
|
||||
* @param string $fieldName
|
||||
@@ -458,6 +624,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理Float类型。
|
||||
* Float fixer.
|
||||
*
|
||||
* @param string $fieldName
|
||||
@@ -472,6 +639,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理Int类型。
|
||||
* Int fixer.
|
||||
*
|
||||
* @param string $fieldName
|
||||
@@ -486,7 +654,8 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* Special chars
|
||||
* 将字符串转换为可以在浏览器查看的编码。
|
||||
* Special chars.
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @access public
|
||||
@@ -519,10 +688,11 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip tags
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @param string $allowedTags
|
||||
* 忽略该标签。
|
||||
* Strip tags
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @param string $allowableTags
|
||||
* @access public
|
||||
* @return object fixer object
|
||||
*/
|
||||
@@ -545,14 +715,18 @@ class fixer
|
||||
{
|
||||
if(version_compare(phpversion(), '5.4', '<') and get_magic_quotes_gpc()) $this->data->$fieldName = stripslashes($this->data->$fieldName);
|
||||
|
||||
if(!in_array($fieldName, $this->stripedFields)) $this->data->$fieldName = $purifier->purify($this->data->$fieldName);
|
||||
if(!in_array($fieldName, $this->stripedFields))
|
||||
{
|
||||
if(!defined('RUN_MODE') or RUN_MODE != 'admin') $this->data->$fieldName = $purifier->purify($this->data->$fieldName);
|
||||
}
|
||||
$this->stripedFields[] = $fieldName;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip special chars.
|
||||
* 忽略处理给定的字段。
|
||||
* Skip special chars check.
|
||||
*
|
||||
* @param string $filename
|
||||
* @access public
|
||||
@@ -566,6 +740,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 给字段添加引用,防止字符与关键字冲突。
|
||||
* Quote
|
||||
*
|
||||
* @param string $fieldName
|
||||
@@ -580,6 +755,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置字段的默认值。
|
||||
* Set default value of some fileds.
|
||||
*
|
||||
* @param string $fields
|
||||
@@ -595,6 +771,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果条件为真,则为字段赋值。
|
||||
* Set value of a filed on the condition is true.
|
||||
*
|
||||
* @param bool $condition
|
||||
@@ -610,6 +787,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制给字段赋值。
|
||||
* Set the value of a filed in force.
|
||||
*
|
||||
* @param string $fieldName
|
||||
@@ -624,6 +802,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除一个字段。
|
||||
* Remove a field.
|
||||
*
|
||||
* @param string $fieldName
|
||||
@@ -638,6 +817,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果条件为真,移除该字段。
|
||||
* Remove a filed on the condition is true.
|
||||
*
|
||||
* @param bool $condition
|
||||
@@ -653,6 +833,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 为数据添加新的项。
|
||||
* Add an item to the data.
|
||||
*
|
||||
* @param string $fieldName
|
||||
@@ -667,6 +848,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果条件为真,则为数据添加新的项。
|
||||
* Add an item to the data on the condition if true.
|
||||
*
|
||||
* @param bool $condition
|
||||
@@ -682,6 +864,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定字段增加值。
|
||||
* Join the field.
|
||||
*
|
||||
* @param string $fieldName
|
||||
@@ -697,6 +880,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用一个方法来处理数据。
|
||||
* Call a function to fix it.
|
||||
*
|
||||
* @param string $fieldName
|
||||
@@ -712,14 +896,12 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理完成后返回数据。
|
||||
* Get the data after fixing.
|
||||
*
|
||||
* If only one field, return it's value directly.
|
||||
* More fields, remove other fields not in the list and return $data.
|
||||
*
|
||||
* @param string $fields the fields list.
|
||||
* @param string $fieldName
|
||||
* @access public
|
||||
* @return mix
|
||||
* @return object
|
||||
*/
|
||||
public function get($fields = '')
|
||||
{
|
||||
@@ -740,6 +922,7 @@ class fixer
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理字段,如果字段中含有',',拆分成数组。如果字段不在$data中,删除掉。
|
||||
* Process fields, if contains ',', split it to array. If not in $data, remove it.
|
||||
*
|
||||
* @param string $fields
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
157
lib/pager/pager.class.php
Executable file → Normal file
157
lib/pager/pager.class.php
Executable file → Normal file
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* ZenTaoPHP的分页类。
|
||||
* The pager class file of ZenTaoPHP framework.
|
||||
*
|
||||
* The author disclaims copyright to this source code. In place of
|
||||
@@ -10,6 +11,7 @@
|
||||
* May you share freely, never taking more than you give.
|
||||
*/
|
||||
/**
|
||||
* pager类.
|
||||
* Pager class.
|
||||
*
|
||||
* @package framework
|
||||
@@ -17,13 +19,15 @@
|
||||
class pager
|
||||
{
|
||||
/**
|
||||
* 每页的默认显示记录数。
|
||||
* The default counts of per page.
|
||||
*
|
||||
* @public int
|
||||
*/
|
||||
const DEFAULT_REC_PRE_PAGE = 20;
|
||||
const DEFAULT_REC_PER_PAGE = 20;
|
||||
|
||||
/**
|
||||
* 总个数。
|
||||
* The total counts.
|
||||
*
|
||||
* @var int
|
||||
@@ -32,6 +36,7 @@ class pager
|
||||
public $recTotal;
|
||||
|
||||
/**
|
||||
* 每页的记录数。
|
||||
* Record count per page.
|
||||
*
|
||||
* @var int
|
||||
@@ -48,6 +53,7 @@ class pager
|
||||
public $pageCookie;
|
||||
|
||||
/**
|
||||
* 总页面数。
|
||||
* Page count.
|
||||
*
|
||||
* @var string
|
||||
@@ -56,6 +62,7 @@ class pager
|
||||
public $pageTotal;
|
||||
|
||||
/**
|
||||
* 当前页码。
|
||||
* Current page id.
|
||||
*
|
||||
* @var string
|
||||
@@ -64,6 +71,7 @@ class pager
|
||||
public $pageID;
|
||||
|
||||
/**
|
||||
* 全局变量$app。
|
||||
* The global $app.
|
||||
*
|
||||
* @var object
|
||||
@@ -72,6 +80,7 @@ class pager
|
||||
private $app;
|
||||
|
||||
/**
|
||||
* 全局变量$lang。
|
||||
* The global $lang.
|
||||
*
|
||||
* @var object
|
||||
@@ -80,6 +89,7 @@ class pager
|
||||
private $lang;
|
||||
|
||||
/**
|
||||
* 当前的模块名。
|
||||
* Current module name.
|
||||
*
|
||||
* @var string
|
||||
@@ -88,6 +98,7 @@ class pager
|
||||
private $moduleName;
|
||||
|
||||
/**
|
||||
* 当前的方法名。
|
||||
* Current method.
|
||||
*
|
||||
* @var string
|
||||
@@ -96,6 +107,7 @@ class pager
|
||||
private $methodName;
|
||||
|
||||
/**
|
||||
* 参数信息。
|
||||
* The params.
|
||||
*
|
||||
* @private array
|
||||
@@ -103,6 +115,7 @@ class pager
|
||||
private $params;
|
||||
|
||||
/**
|
||||
* 构造方法。
|
||||
* The construct function.
|
||||
*
|
||||
* @param int $recTotal
|
||||
@@ -125,6 +138,7 @@ class pager
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造方法。
|
||||
* The factory function.
|
||||
*
|
||||
* @param int $recTotal
|
||||
@@ -139,6 +153,7 @@ class pager
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置总记录数。
|
||||
* Set the recTotal property.
|
||||
*
|
||||
* @param int $recTotal
|
||||
@@ -151,7 +166,8 @@ class pager
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the recTotal property.
|
||||
* 设置每页记录数。
|
||||
* Set the recPerPage property.
|
||||
*
|
||||
* @param int $recPerPage
|
||||
* @access public
|
||||
@@ -163,10 +179,11 @@ class pager
|
||||
$this->pageCookie = 'pager' . ucfirst($this->app->getModuleName()) . ucfirst($this->app->getMethodName());
|
||||
|
||||
if(isset($_COOKIE[$this->pageCookie])) $recPerPage = $_COOKIE[$this->pageCookie];
|
||||
$this->recPerPage = ($recPerPage > 0) ? $recPerPage : PAGER::DEFAULT_REC_PRE_PAGE;
|
||||
$this->recPerPage = ($recPerPage > 0) ? $recPerPage : PAGER::DEFAULT_REC_PER_PAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置总页数。
|
||||
* Set the pageTotal property.
|
||||
*
|
||||
* @access public
|
||||
@@ -178,6 +195,7 @@ class pager
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置页码。
|
||||
* Set the page id.
|
||||
*
|
||||
* @param int $pageID
|
||||
@@ -186,7 +204,7 @@ class pager
|
||||
*/
|
||||
public function setPageID($pageID)
|
||||
{
|
||||
if($pageID > 0 and $pageID <= $this->pageTotal)
|
||||
if($pageID > 0 and ($this->pageTotal == 0 or $pageID <= $this->pageTotal))
|
||||
{
|
||||
$this->pageID = $pageID;
|
||||
}
|
||||
@@ -197,6 +215,7 @@ class pager
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置全局变量$app。
|
||||
* Set the $app property;
|
||||
*
|
||||
* @access private
|
||||
@@ -209,6 +228,7 @@ class pager
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置全局变量$lang。
|
||||
* Set the $lang property.
|
||||
*
|
||||
* @access private
|
||||
@@ -221,6 +241,7 @@ class pager
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模块名。
|
||||
* Set the $moduleName property.
|
||||
*
|
||||
* @access private
|
||||
@@ -232,6 +253,7 @@ class pager
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置方法名。
|
||||
* Set the $methodName property.
|
||||
*
|
||||
* @access private
|
||||
@@ -243,6 +265,7 @@ class pager
|
||||
}
|
||||
|
||||
/**
|
||||
* 从请求网址中获取记录总数、每页记录数、页码。
|
||||
* Get recTotal, recPerpage, pageID from the request params, and add them to params.
|
||||
*
|
||||
* @access private
|
||||
@@ -257,9 +280,19 @@ class pager
|
||||
if(strtolower($key) == 'recperpage') $this->params[$key] = $this->recPerPage;
|
||||
if(strtolower($key) == 'pageid') $this->params[$key] = $this->pageID;
|
||||
}
|
||||
|
||||
parse_str(strip_tags(urldecode($_SERVER['QUERY_STRING'])), $query);
|
||||
|
||||
unset($query['m']);
|
||||
unset($query['f']);
|
||||
unset($query['t']);
|
||||
|
||||
$this->params = array_merge($this->params, $query);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建limit语句。
|
||||
* Create the limit string.
|
||||
*
|
||||
* @access public
|
||||
@@ -271,8 +304,9 @@ class pager
|
||||
if($this->pageTotal > 1) $limit = ' limit ' . ($this->pageID - 1) * $this->recPerPage . ", $this->recPerPage";
|
||||
return $limit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 向页面显示分页信息。
|
||||
* Print the pager's html.
|
||||
*
|
||||
* @param string $align
|
||||
@@ -282,10 +316,48 @@ class pager
|
||||
*/
|
||||
public function show($align = 'right', $type = 'full')
|
||||
{
|
||||
echo $this->get($align, $type);
|
||||
if($align === 'justify')
|
||||
{
|
||||
echo $this->getJustify($type);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo $this->get($align, $type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取优化后的分页。
|
||||
* Get the justify pager html string
|
||||
*
|
||||
* @access public
|
||||
* @return [type] [description]
|
||||
*/
|
||||
public function getJustify()
|
||||
{
|
||||
if($this->recTotal <= 0) return '';
|
||||
|
||||
$this->setParams();
|
||||
$pager = '';
|
||||
|
||||
$pager .= "<li class='previous" . ($this->pageID == 1 ? ' disabled' : '') . "'>";
|
||||
$this->params['pageID'] = 1;
|
||||
$pager .= $this->createLink('« ' . $this->lang->pager->previousPage) . '</li>';
|
||||
|
||||
$pager .= "<li class='caption'>";
|
||||
$firstId = $this->recPerPage * ($this->pageID - 1) + 1;
|
||||
$pager .= sprintf($this->lang->pager->summery, $firstId, max(min($this->recPerPage * $this->pageID, $this->recTotal), $firstId), $this->recTotal);
|
||||
$pager .= '</li>';
|
||||
|
||||
$pager .= "<li class='next" . (($this->pageID == $this->pageTotal || $this->pageTotal <= 1) ? ' disabled' : '') . "'>";
|
||||
$this->params['pageID'] = min($this->pageTotal, $this->pageID + 1);
|
||||
$pager .= $this->createLink($this->lang->pager->nextPage . ' »') . '</li>';
|
||||
|
||||
return "<ul class='pager pager-justify'>{$pager}</ul>";
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置分页信息的样式。
|
||||
* Get the pager html string.
|
||||
*
|
||||
* @param string $align
|
||||
@@ -295,17 +367,19 @@ class pager
|
||||
*/
|
||||
public function get($align = 'right', $type = 'full')
|
||||
{
|
||||
/* 如果记录个数为0,返回没有记录。 */
|
||||
/* If the RecTotal is zero, return with no record. */
|
||||
if($this->recTotal == 0) { return $type == 'mobile' ? '' : "<div style='float:$align; clear:none;' class='pager'>{$this->lang->pager->noRecord}</div>"; }
|
||||
if($this->recTotal == 0) return $type == 'mobile' ? '' : "<div style='float:$align; clear:none;' class='page'>{$this->lang->pager->noRecord}</div>";
|
||||
|
||||
/* Set the params. */
|
||||
$this->setParams();
|
||||
|
||||
|
||||
/* 创建前一页和后一页链接。 */
|
||||
/* Create the prePage and nextpage, all types have them. */
|
||||
$pager = $this->createPrePage($type);
|
||||
$pager .= $this->createNextPage($type);
|
||||
|
||||
/* The short and full type. */
|
||||
/* 简单和完全模式。 The short and full type. */
|
||||
if($type !== 'shortest' and $type !== 'mobile')
|
||||
{
|
||||
$pager = $this->createFirstPage() . $pager;
|
||||
@@ -322,7 +396,7 @@ class pager
|
||||
$pager = $this->pageID . '/' . $this->pageTotal . ' ' . $pager;
|
||||
}
|
||||
|
||||
/* Only the full type . */
|
||||
/* 只是完全模式。 Only the full type . */
|
||||
if($type == 'full')
|
||||
{
|
||||
$pager = $this->createDigest() . $pager;
|
||||
@@ -330,10 +404,11 @@ class pager
|
||||
$pager .= $this->createRecPerPageJS();
|
||||
}
|
||||
|
||||
return "<div style='float:$align; clear:none;' class='pager'>$pager</div>";
|
||||
return "<div style='float:$align; clear:none;' class='pager form-inline'>$pager</div>";
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成分页摘要信息。
|
||||
* Create the digest code.
|
||||
*
|
||||
* @access private
|
||||
@@ -345,6 +420,7 @@ class pager
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建首页链接。
|
||||
* Create the first page.
|
||||
*
|
||||
* @access private
|
||||
@@ -354,12 +430,14 @@ class pager
|
||||
{
|
||||
if($this->pageID == 1) return $this->lang->pager->first . ' ';
|
||||
$this->params['pageID'] = 1;
|
||||
return html::a(helper::createLink($this->moduleName, $this->methodName, $this->params), $this->lang->pager->first);
|
||||
return $this->createLink($this->lang->pager->first);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建前一页链接。
|
||||
* Create the pre page html.
|
||||
*
|
||||
* @param string $type
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
@@ -369,19 +447,21 @@ class pager
|
||||
{
|
||||
if($this->pageID == 1) return '';
|
||||
$this->params['pageID'] = $this->pageID - 1;
|
||||
return html::a(helper::createLink($this->moduleName, $this->methodName, $this->params), $this->lang->pager->pre, '', 'data-role="button" data-icon="arrow-l" data-iconpos="left" data-inline="true"');
|
||||
return $this->createLink($this->lang->pager->pre);
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->pageID == 1) return $this->lang->pager->pre . ' ';
|
||||
$this->params['pageID'] = $this->pageID - 1;
|
||||
return html::a(helper::createLink($this->moduleName, $this->methodName, $this->params), $this->lang->pager->pre);
|
||||
return $this->createLink($this->lang->pager->pre);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建下一页链接。
|
||||
* Create the next page html.
|
||||
*
|
||||
* @param string $type
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
@@ -391,17 +471,18 @@ class pager
|
||||
{
|
||||
if($this->pageID == $this->pageTotal) return '';
|
||||
$this->params['pageID'] = $this->pageID + 1;
|
||||
return html::a(helper::createLink($this->moduleName, $this->methodName, $this->params), $this->lang->pager->next, '', 'data-role="button" data-icon="arrow-r" data-iconpos="right" data-inline="true"');
|
||||
return $this->createLink($this->lang->pager->next);
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->pageID == $this->pageTotal) return $this->lang->pager->next . ' ';
|
||||
$this->params['pageID'] = $this->pageID + 1;
|
||||
return html::a(helper::createLink($this->moduleName, $this->methodName, $this->params), $this->lang->pager->next);
|
||||
return $this->createLink($this->lang->pager->next);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建最后一页链接。
|
||||
* Create the last page
|
||||
*
|
||||
* @access private
|
||||
@@ -411,10 +492,11 @@ class pager
|
||||
{
|
||||
if($this->pageID == $this->pageTotal) return $this->lang->pager->last . ' ';
|
||||
$this->params['pageID'] = $this->pageTotal;
|
||||
return html::a(helper::createLink($this->moduleName, $this->methodName, $this->params), $this->lang->pager->last);
|
||||
return $this->createLink($this->lang->pager->last);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建每页显示记录数的select标签。
|
||||
* Create the select object of record perpage.
|
||||
*
|
||||
* @access private
|
||||
@@ -422,7 +504,10 @@ class pager
|
||||
*/
|
||||
private function createRecPerPageJS()
|
||||
{
|
||||
/* Replace the recTotal, recPerPage, pageID to special string, and then replace them with values by JS. */
|
||||
/*
|
||||
* 替换recTotal, recPerPage, pageID为特殊的字符串,然后用js代码替换掉。
|
||||
* Replace the recTotal, recPerPage, pageID to special string, and then replace them with values by JS.
|
||||
**/
|
||||
$params = $this->params;
|
||||
foreach($params as $key => $value)
|
||||
{
|
||||
@@ -435,7 +520,7 @@ class pager
|
||||
$vars = rtrim($vars, '&');
|
||||
|
||||
$js = <<<EOT
|
||||
<script>
|
||||
<script language='Javascript'>
|
||||
vars = '$vars';
|
||||
pageCookie = '$this->pageCookie';
|
||||
function submitPage(mode, perPage)
|
||||
@@ -467,6 +552,7 @@ EOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成每页显示记录数的select列表。
|
||||
* Create the select list of RecPerPage.
|
||||
*
|
||||
* @access private
|
||||
@@ -479,6 +565,7 @@ EOT;
|
||||
$range[200] = 200;
|
||||
$range[500] = 500;
|
||||
$range[1000] = 1000;
|
||||
$range[2000] = 2000;
|
||||
$html = "<div class='dropdown dropup'><a href='javascript:;' data-toggle='dropdown' id='_recPerPage' data-value='{$this->recPerPage}'>" . (sprintf($this->lang->pager->recPerPage, $this->recPerPage)) . "<span class='caret'></span></a><ul class='dropdown-menu'>";
|
||||
foreach ($range as $key => $value)
|
||||
{
|
||||
@@ -489,6 +576,7 @@ EOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成跳转到指定页码的部分。
|
||||
* Create the goto part html.
|
||||
*
|
||||
* @access private
|
||||
@@ -498,8 +586,35 @@ EOT;
|
||||
{
|
||||
$goToHtml = "<input type='hidden' id='_recTotal' value='$this->recTotal' />\n";
|
||||
$goToHtml .= "<input type='hidden' id='_pageTotal' value='$this->pageTotal' />\n";
|
||||
$goToHtml .= "<input type='text' id='_pageID' value='$this->pageID' style='text-align:center;width:30px;' class='form-control' /> \n";
|
||||
$goToHtml .= "<input type='button' id='goto' value='{$this->lang->pager->locate}' onclick='submitPage(\"changePageID\");' class='btn'/>";
|
||||
$goToHtml .= "<input type='text' id='_pageID' value='$this->pageID' style='text-align:center;width:30px;' class='form-control' /> \n";
|
||||
$goToHtml .= "<input type='button' id='goto' value='{$this->lang->pager->locate}' onclick='submitPage(\"changePageID\");' class='btn'/>";
|
||||
return $goToHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建链接。
|
||||
* Create link.
|
||||
*
|
||||
* @param string $title
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
private function createLink($title)
|
||||
{
|
||||
global $config;
|
||||
if(helper::inSeoMode() && method_exists('uri', 'create' . $this->moduleName . $this->methodName))
|
||||
{
|
||||
$link = strip_tags(urldecode($_SERVER['REQUEST_URI']));
|
||||
|
||||
if($this->params['pageID'] == 1) return html::a(preg_replace('/\/p\d+\./', '.', $link), $title);
|
||||
|
||||
if(preg_match('/\/p\d+/', $link)) return html::a(preg_replace('/\/p\d+\./', '/p' . $this->params['pageID'] . '.', $link), $title);
|
||||
|
||||
if($config->requestType == 'PATH_INFO2') $link = str_replace('index.php/', 'index_php/', $link);
|
||||
$link = str_replace('.', "/p{$this->params['pageID']}.", $link);
|
||||
if($config->requestType == 'PATH_INFO2') $link = str_replace('index_php/', 'index.php/', $link);
|
||||
return html::a($link, $title);
|
||||
}
|
||||
return html::a(helper::createLink($this->moduleName, $this->methodName, $this->params), $title);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<tr class='text-center'>
|
||||
<td><?php echo zget($lang->action->objectTypes, $action->objectType, '');?></td>
|
||||
<td><?php echo $action->objectID;?></td>
|
||||
<td class='text-left'><?php echo html::a($this->createLink($module, 'view', "id=$action->objectID"), $action->objectName);?></td>
|
||||
<td class='text-left'><?php echo html::a($this->createLink($module, 'view', $action->objectType == 'user' ? "account={$action->objectName}" : "id={$action->objectID}"), $action->objectName);?></td>
|
||||
<td><?php echo $users[$action->actor];?></td>
|
||||
<td><?php echo $action->date;?></td>
|
||||
<td>
|
||||
|
||||
@@ -52,6 +52,7 @@ class bug extends control
|
||||
* Browse bugs.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param string $branch
|
||||
* @param string $browseType
|
||||
* @param int $param
|
||||
* @param string $orderBy
|
||||
@@ -63,10 +64,10 @@ class bug extends control
|
||||
*/
|
||||
public function browse($productID = 0, $branch = '', $browseType = 'unclosed', $param = 0, $orderBy = '', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
/* Set browseType, productID, moduleID and queryID. */
|
||||
/* Set browseType, productID, moduleID, queryID and branch. */
|
||||
$browseType = strtolower($browseType);
|
||||
$productID = $this->product->saveState($productID, $this->products);
|
||||
if($branch === '') $branch = $this->session->branch;
|
||||
$branch = ($branch == '') ? $this->session->branch : $branch;
|
||||
$moduleID = ($browseType == 'bymodule') ? (int)$param : 0;
|
||||
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
|
||||
|
||||
@@ -86,98 +87,44 @@ class bug extends control
|
||||
if($this->app->getViewType() == 'mhtml') $recPerPage = 10;
|
||||
$pager = pager::init($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$projects = $this->loadModel('project')->getPairs();
|
||||
$projects[0] = '';
|
||||
/* Get projects. */
|
||||
$projects = $this->loadModel('project')->getPairs() + array('0' => '');
|
||||
|
||||
/* Get bugs. */
|
||||
$bugs = array();
|
||||
if($browseType == 'all') $bugs = $this->bug->getAllBugs($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == "bymodule")
|
||||
{
|
||||
$childModuleIds = $this->tree->getAllChildId($moduleID);
|
||||
$bugs = $this->bug->getModuleBugs($productID, $branch, $childModuleIds, $projects, $sort, $pager);
|
||||
}
|
||||
elseif($browseType == 'assigntome') $bugs = $this->bug->getByAssigntome($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'openedbyme') $bugs = $this->bug->getByOpenedbyme($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'resolvedbyme') $bugs = $this->bug->getByResolvedbyme($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'assigntonull') $bugs = $this->bug->getByAssigntonull($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'unconfirmed') $bugs = $this->bug->getUnconfirmed($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'unresolved') $bugs = $this->bug->getByStatus($productID, $branch, $projects, 'unresolved', $sort, $pager);
|
||||
elseif($browseType == 'unclosed') $bugs = $this->bug->getByStatus($productID, $branch, $projects, 'unclosed', $sort, $pager);
|
||||
elseif($browseType == 'toclosed') $bugs = $this->bug->getByStatus($productID, $branch, $projects, 'toclosed', $sort, $pager);
|
||||
elseif($browseType == 'longlifebugs') $bugs = $this->bug->getByLonglifebugs($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'postponedbugs') $bugs = $this->bug->getByPostponedbugs($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'needconfirm') $bugs = $this->bug->getByNeedconfirm($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'bysearch') $bugs = $this->bug->getBySearch($productID, $queryID, $sort, $pager, $branch);
|
||||
$bugs = $this->bug->getBugs($productID, $projects, $branch, $browseType, $moduleID, $queryID, $sort, $pager);
|
||||
|
||||
/* Process the sql, get the conditon partion, save it to session. */
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'bug', $browseType == 'needconfirm' ? false : true);
|
||||
|
||||
/* Process bug for check story changed. */
|
||||
$bugs = $this->loadModel('story')->checkNeedConfirm($bugs);
|
||||
|
||||
/* Build the search form. */
|
||||
$this->config->bug->search['actionURL'] = $this->createLink('bug', 'browse', "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID");
|
||||
$this->config->bug->search['queryID'] = $queryID;
|
||||
$this->config->bug->search['params']['product']['values'] = array($productID => $this->products[$productID], 'all' => $this->lang->bug->allProduct);
|
||||
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairs($productID);
|
||||
$this->config->bug->search['params']['module']['values'] = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0);
|
||||
$this->config->bug->search['params']['project']['values'] = $this->product->getProjectPairs($productID);
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getProductBuildPairs($productID, 0, $params = '');
|
||||
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
|
||||
if($this->session->currentProductType == 'normal')
|
||||
{
|
||||
unset($this->config->bug->search['fields']['branch']);
|
||||
unset($this->config->bug->search['params']['branch']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->config->bug->search['fields']['branch'] = $this->lang->product->branch;
|
||||
$this->config->bug->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty');
|
||||
}
|
||||
$this->loadModel('search')->setSearchParams($this->config->bug->search);
|
||||
|
||||
$users = $this->user->getPairs('noletter');
|
||||
$bugs = $this->loadModel('story')->checkNeedConfirm($bugs);
|
||||
|
||||
/* Process the openedBuild and resolvedBuild fields. */
|
||||
$productIdList = array();
|
||||
foreach($bugs as $bug) $productIdList[$bug->id] = $bug->product;
|
||||
$builds = $this->loadModel('build')->getProductBuildPairs(array_unique($productIdList), 0, $params = '');
|
||||
foreach($bugs as $key => $bug)
|
||||
{
|
||||
$openBuildIdList = explode(',', $bug->openedBuild);
|
||||
$openedBuild = '';
|
||||
foreach($openBuildIdList as $buildID)
|
||||
{
|
||||
$openedBuild .= isset($builds[$buildID]) ? $builds[$buildID] : $buildID;
|
||||
$openedBuild .= ',';
|
||||
}
|
||||
$bug->openedBuild = rtrim($openedBuild, ',');
|
||||
$bug->resolvedBuild = isset($builds[$bug->resolvedBuild]) ? $builds[$bug->resolvedBuild] : $bug->resolvedBuild;
|
||||
}
|
||||
$bugs = $this->bug->processBuildForBugs($bugs);
|
||||
|
||||
$memberPairs = $this->user->getPairs('noletter|nodeleted');
|
||||
|
||||
$title = $this->products[$productID] . $this->lang->colon . $this->lang->bug->common;
|
||||
$position[] = html::a($this->createLink('bug', 'browse', "productID=$productID"), $this->products[$productID]);
|
||||
$position[] = $this->lang->bug->common;
|
||||
/* Build the search form. */
|
||||
$actionURL = $this->createLink('bug', 'browse', "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID");
|
||||
$this->bug->buildSearchForm($productID, $this->products, $queryID, $actionURL);
|
||||
$this->loadModel('search')->setSearchParams($this->config->bug->search);
|
||||
|
||||
$this->view->title = $title;
|
||||
$this->view->position = $position;
|
||||
$this->view->productID = $productID;
|
||||
$this->view->productName = $this->products[$productID];
|
||||
$this->view->builds = $this->loadModel('build')->getProductBuildPairs($productID);
|
||||
$this->view->moduleTree = $this->tree->getTreeMenu($productID, $viewType = 'bug', $startModuleID = 0, array('treeModel', 'createBugLink'), '', $branch);
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->bugs = $bugs;
|
||||
$this->view->users = $users;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->param = $param;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->moduleID = $moduleID;
|
||||
$this->view->memberPairs = $memberPairs;
|
||||
$this->view->branch = $branch;
|
||||
$this->view->branches = $this->loadModel('branch')->getPairs($productID);
|
||||
/* Set view. */
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->bug->common;
|
||||
$this->view->position[] = html::a($this->createLink('bug', 'browse', "productID=$productID"), $this->products[$productID]);
|
||||
$this->view->position[] = $this->lang->bug->common;
|
||||
$this->view->productID = $productID;
|
||||
$this->view->productName = $this->products[$productID];
|
||||
$this->view->builds = $this->loadModel('build')->getProductBuildPairs($productID);
|
||||
$this->view->moduleTree = $this->tree->getTreeMenu($productID, $viewType = 'bug', $startModuleID = 0, array('treeModel', 'createBugLink'), '', $branch);
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->bugs = $bugs;
|
||||
$this->view->users = $this->user->getPairs('noletter');
|
||||
$this->view->pager = $pager;
|
||||
$this->view->param = $param;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->moduleID = $moduleID;
|
||||
$this->view->memberPairs = $this->user->getPairs('noletter|nodeleted');
|
||||
$this->view->branch = $branch;
|
||||
$this->view->branches = $this->loadModel('branch')->getPairs($productID);
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -351,7 +298,7 @@ class bug extends control
|
||||
$this->view->productName = $this->products[$productID];
|
||||
$this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, $branch);
|
||||
$this->view->stories = $stories;
|
||||
$this->view->projects = $this->product->getProjectPairs($productID, $branch, $params = 'nodeleted');
|
||||
$this->view->projects = $this->product->getProjectPairs($productID, $branch ? "0,$branch" : 0, $params = 'nodeleted');
|
||||
$this->view->builds = $builds;
|
||||
$this->view->moduleID = $moduleID;
|
||||
$this->view->projectID = $projectID;
|
||||
@@ -434,7 +381,7 @@ class bug extends control
|
||||
$this->view->stories = $stories;
|
||||
$this->view->builds = $builds;
|
||||
$this->view->users = $this->user->getPairs('nodeleted,devfirst');
|
||||
$this->view->projects = $this->product->getProjectPairs($productID, $branch, $params = 'nodeleted');
|
||||
$this->view->projects = $this->product->getProjectPairs($productID, $branch ? "0,$branch" : 0, $params = 'nodeleted');
|
||||
$this->view->projectID = $projectID;
|
||||
$this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, $branch);
|
||||
$this->view->moduleID = $moduleID;
|
||||
@@ -580,7 +527,7 @@ class bug extends control
|
||||
$this->view->plans = $this->loadModel('productplan')->getPairs($productID, $bug->branch);
|
||||
$this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, $bug->branch);
|
||||
$this->view->currentModuleID = $currentModuleID;
|
||||
$this->view->projects = $this->product->getProjectPairs($bug->product, $bug->branch);
|
||||
$this->view->projects = $this->product->getProjectPairs($bug->product, $bug->branch ? "0,{$bug->branch}" : 0, 'nodeleted');
|
||||
$this->view->stories = $bug->project ? $this->story->getProjectStoryPairs($bug->project) : $this->story->getProductStoryPairs($bug->product, $bug->branch);
|
||||
$this->view->branches = $this->session->currentProductType == 'normal' ? array() : $this->loadModel('branch')->getPairs($bug->product);
|
||||
$this->view->tasks = $this->task->getProjectTaskPairs($bug->project);
|
||||
@@ -1177,7 +1124,8 @@ class bug extends control
|
||||
}
|
||||
|
||||
/* Get action info. */
|
||||
$action = $this->action->getById($actionID);
|
||||
$actions = $this->action->getList('bug', $bugID);
|
||||
$action = zget($actions, $actionID, null);
|
||||
$history = $this->action->getHistory($actionID);
|
||||
$action->history = isset($history[$actionID]) ? $history[$actionID] : array();
|
||||
if(strtolower($action->action) == 'opened') $action->comment = $bug->steps;
|
||||
|
||||
@@ -20,4 +20,5 @@ $(document).ready(function()
|
||||
});
|
||||
});
|
||||
setTimeout(function(){fixedTfootAction('#bugForm')}, 100);
|
||||
setTimeout(function(){fixedTheadOfList('#bugList')}, 100);
|
||||
});
|
||||
|
||||
@@ -200,6 +200,43 @@ class bugModel extends model
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bugs.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param array $projects
|
||||
* @param int $branch
|
||||
* @param string $browseType
|
||||
* @param int $moduleID
|
||||
* @param int $queryID
|
||||
* @param string $sort
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getBugs($productID, $projects, $branch, $browseType, $moduleID, $queryID, $sort, $pager)
|
||||
{
|
||||
/* Get bugs by browse type. */
|
||||
if($browseType == 'all') $bugs = $this->getAllBugs($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'bymodule') $bugs = $this->getModuleBugs($productID, $branch, $this->loadModel('tree')->getAllChildId($moduleID), $projects, $sort, $pager);
|
||||
elseif($browseType == 'assigntome') $bugs = $this->getByAssigntome($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'openedbyme') $bugs = $this->getByOpenedbyme($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'resolvedbyme') $bugs = $this->getByResolvedbyme($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'assigntonull') $bugs = $this->getByAssigntonull($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'unconfirmed') $bugs = $this->getUnconfirmed($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'unresolved') $bugs = $this->getByStatus($productID, $branch, $projects, 'unresolved', $sort, $pager);
|
||||
elseif($browseType == 'unclosed') $bugs = $this->getByStatus($productID, $branch, $projects, 'unclosed', $sort, $pager);
|
||||
elseif($browseType == 'toclosed') $bugs = $this->getByStatus($productID, $branch, $projects, 'toclosed', $sort, $pager);
|
||||
elseif($browseType == 'longlifebugs') $bugs = $this->getByLonglifebugs($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'postponedbugs') $bugs = $this->getByPostponedbugs($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'needconfirm') $bugs = $this->getByNeedconfirm($productID, $branch, $projects, $sort, $pager);
|
||||
elseif($browseType == 'bysearch') $bugs = $this->getBySearch($productID, $queryID, $sort, $pager, $branch);
|
||||
|
||||
if($bugs) return $bugs;
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bugs of a module.
|
||||
*
|
||||
@@ -757,6 +794,68 @@ class bugModel extends model
|
||||
$this->dao->update(TABLE_BUG)->data($bug)->autoCheck()->where('id')->eq((int)$bugID)->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build search form.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param array $products
|
||||
* @param int $queryID
|
||||
* @param string $actionURL
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function buildSearchForm($productID, $products, $queryID, $actionURL)
|
||||
{
|
||||
$this->config->bug->search['actionURL'] = $actionURL;
|
||||
$this->config->bug->search['queryID'] = $queryID;
|
||||
$this->config->bug->search['params']['product']['values'] = array($productID => $products[$productID], 'all' => $this->lang->bug->allProduct);
|
||||
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairs($productID);
|
||||
$this->config->bug->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0);
|
||||
$this->config->bug->search['params']['project']['values'] = $this->product->getProjectPairs($productID);
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getProductBuildPairs($productID, 0, $params = '');
|
||||
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
|
||||
if($this->session->currentProductType == 'normal')
|
||||
{
|
||||
unset($this->config->bug->search['fields']['branch']);
|
||||
unset($this->config->bug->search['params']['branch']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->config->bug->search['fields']['branch'] = $this->lang->product->branch;
|
||||
$this->config->bug->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the openedBuild and resolvedBuild fields for bugs.
|
||||
*
|
||||
* @param array $bugs
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function processBuildForBugs($bugs)
|
||||
{
|
||||
$productIdList = array();
|
||||
foreach($bugs as $bug) $productIdList[$bug->id] = $bug->product;
|
||||
$builds = $this->loadModel('build')->getProductBuildPairs(array_unique($productIdList), 0, $params = '');
|
||||
|
||||
/* Process the openedBuild and resolvedBuild fields. */
|
||||
foreach($bugs as $key => $bug)
|
||||
{
|
||||
$openBuildIdList = explode(',', $bug->openedBuild);
|
||||
$openedBuild = '';
|
||||
foreach($openBuildIdList as $buildID)
|
||||
{
|
||||
$openedBuild .= isset($builds[$buildID]) ? $builds[$buildID] : $buildID;
|
||||
$openedBuild .= ',';
|
||||
}
|
||||
$bug->openedBuild = rtrim($openedBuild, ',');
|
||||
$bug->resolvedBuild = isset($builds[$bug->resolvedBuild]) ? $builds[$bug->resolvedBuild] : $bug->resolvedBuild;
|
||||
}
|
||||
|
||||
return $bugs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract accounts from some bugs.
|
||||
*
|
||||
|
||||
@@ -175,9 +175,7 @@ js::set('moduleID', $moduleID);
|
||||
<td colspan='<?php echo $columns;?>'>
|
||||
<?php if(!empty($bugs)):?>
|
||||
<div class='table-actions clearfix'>
|
||||
<div class='btn-group'>
|
||||
<?php echo html::selectButton();?>
|
||||
</div>
|
||||
<div class='btn-group dropup'>
|
||||
<?php
|
||||
$actionLink = $this->createLink('bug', 'batchEdit', "productID=$productID&branch=$branch");
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<form method='post'>
|
||||
<?php echo html::checkBox('charts', $lang->bug->report->charts, $checkedCharts, '', 'block');?>
|
||||
<?php echo html::selectAll('', "button", false, 'btn-sm')?>
|
||||
<?php echo html::submitButton($lang->bug->report->create, '', "btn-primary btn-sm");?>
|
||||
<?php echo html::submitButton($lang->bug->report->create, '', "btn btn-primary btn-sm");?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -281,7 +281,7 @@
|
||||
<table class='table table-data table-condensed table-borderless table-fixed'>
|
||||
<tr>
|
||||
<th class='w-60px'><?php echo $lang->bug->fromCase;?></th>
|
||||
<td><?php if($bug->case) echo html::a($this->createLink('testcase', 'view', "caseID=$bug->case"), $bug->caseTitle);?></td>
|
||||
<td><?php if($bug->case) echo html::a($this->createLink('testcase', 'view', "caseID=$bug->case"), "#$bug->case $bug->caseTitle", '_blank');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->bug->toCase;?></th>
|
||||
@@ -308,10 +308,6 @@
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->bug->case;?></th>
|
||||
<td><?php if(isset($bug->caseTitle)) echo html::a($this->createLink('testcase', 'view', "caseID=$bug->case"), "#$bug->case $bug->caseTitle", '_blank');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->bug->toStory;?></th>
|
||||
<td><?php if($bug->toStory != 0) echo html::a($this->createLink('story', 'view', "storyID=$bug->toStory"), "#$bug->toStory $bug->toStoryTitle", '_blank');?></td>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
.tabs {position:relative;}
|
||||
|
||||
.tabs .tab-content {padding: 0; border: none; padding-top: 10px;}
|
||||
.tabs .nav-tabs{border-bottom:none;}
|
||||
.tabs .nav-tabs>li{margin-bottom:0px;}
|
||||
|
||||
.tabs .tab-content {padding: 0; border: none;}
|
||||
.tabs .tab-content .tab-pane .action {position: absolute; right: 0; top: -1px;}
|
||||
.tabs .tab-content .tab-pane #querybox {margin:-10px 0 0px; border-top: none;}
|
||||
.tabs .tab-content .tab-pane #querybox form {padding-left:0px;}
|
||||
|
||||
@@ -75,6 +75,7 @@ $lang->nextShortcutKey = '[快捷键:→]';
|
||||
|
||||
$lang->selectAll = '全选';
|
||||
$lang->selectReverse = '反选';
|
||||
$lang->loading = '稍候...';
|
||||
$lang->notFound = '抱歉,您访问的对象并不存在!';
|
||||
$lang->showAll = '[[全部显示]]';
|
||||
$lang->hideClosed = '[[显示进行中]]';
|
||||
|
||||
@@ -183,6 +183,7 @@ class commonModel extends model
|
||||
if($module == 'user' and strpos('login|logout|deny|reset', $method) !== false) return true;
|
||||
if($module == 'api' and $method == 'getsessionid') return true;
|
||||
if($module == 'misc' and $method == 'ping') return true;
|
||||
if($module == 'misc' and $method == 'checktable') return true;
|
||||
if($module == 'block' and $method == 'main') return true;
|
||||
if($module == 'sso' and $method == 'login') return true;
|
||||
if($module == 'sso' and $method == 'logout') return true;
|
||||
|
||||
@@ -19,23 +19,23 @@ $clientTheme = $this->app->getClientTheme();
|
||||
js::exportConfigVars();
|
||||
if($config->debug)
|
||||
{
|
||||
js::import($jsRoot . 'jquery/lib.js', $config->version);
|
||||
js::import($jsRoot . 'zui/min.js', $config->version);
|
||||
js::import($jsRoot . 'my.min.js', $config->version);
|
||||
js::import($jsRoot . 'jquery/lib.js');
|
||||
js::import($jsRoot . 'zui/min.js');
|
||||
js::import($jsRoot . 'my.min.js');
|
||||
|
||||
css::import($themeRoot . 'zui/css/min.css', $config->version);
|
||||
css::import($defaultTheme . 'style.css', $config->version);
|
||||
css::import($themeRoot . 'zui/css/min.css');
|
||||
css::import($defaultTheme . 'style.css');
|
||||
|
||||
css::import($langTheme, $config->version);
|
||||
if(strpos($clientTheme, 'default') === false) css::import($clientTheme . 'style.css', $config->version);
|
||||
css::import($langTheme);
|
||||
if(strpos($clientTheme, 'default') === false) css::import($clientTheme . 'style.css');
|
||||
}
|
||||
else
|
||||
{
|
||||
js::import($jsRoot . 'all.js', $config->version);
|
||||
css::import($defaultTheme . $this->cookie->lang . '.' . $this->cookie->theme . '.css', $config->version);
|
||||
js::import($jsRoot . 'all.js');
|
||||
css::import($defaultTheme . $this->cookie->lang . '.' . $this->cookie->theme . '.css');
|
||||
}
|
||||
|
||||
if(isset($pageCss)) css::internal($pageCss);
|
||||
if(isset($pageCSS)) css::internal($pageCSS);
|
||||
|
||||
echo html::favicon($webRoot . 'favicon.ico');
|
||||
?>
|
||||
|
||||
@@ -19,22 +19,22 @@ $clientTheme = $this->app->getClientTheme();
|
||||
js::exportConfigVars();
|
||||
if($config->debug)
|
||||
{
|
||||
js::import($jsRoot . 'jquery/mobile/jquery-1.10.1.min.js', $config->version);
|
||||
js::import($jsRoot . 'm.my.full.js', $config->version);
|
||||
js::import($jsRoot . 'jquery/mobile/jquery.mobile.min.js', $config->version);
|
||||
js::import($jsRoot . 'jquery/jquery.pjax.js', $config->version);
|
||||
js::import($jsRoot . 'jquery/mobile/jquery-1.10.1.min.js');
|
||||
js::import($jsRoot . 'm.my.full.js');
|
||||
js::import($jsRoot . 'jquery/mobile/jquery.mobile.min.js');
|
||||
js::import($jsRoot . 'jquery/jquery.pjax.js');
|
||||
|
||||
css::import($defaultTheme . 'jquery.mobile.css', $config->version);
|
||||
css::import($defaultTheme . 'm.style.css', $config->version);
|
||||
css::import($langTheme, $config->version);
|
||||
css::import($defaultTheme . 'jquery.mobile.css');
|
||||
css::import($defaultTheme . 'm.style.css');
|
||||
css::import($langTheme);
|
||||
}
|
||||
else
|
||||
{
|
||||
js::import($jsRoot . 'm.all.js', $config->version);
|
||||
css::import($defaultTheme . 'm.' . $this->cookie->lang . '.default.css', $config->version);
|
||||
js::import($jsRoot . 'm.all.js');
|
||||
css::import($defaultTheme . 'm.' . $this->cookie->lang . '.default.css');
|
||||
}
|
||||
|
||||
if(isset($pageCss)) css::internal($pageCss);
|
||||
if(isset($pageCSS)) css::internal($pageCSS);
|
||||
|
||||
echo html::favicon($webRoot . 'favicon.ico');
|
||||
?>
|
||||
|
||||
@@ -65,35 +65,15 @@ class company extends control
|
||||
$sort = $this->loadModel('common')->appendOrder($orderBy);
|
||||
|
||||
/* Build the search form. */
|
||||
$queryID = $type == 'bydept' ? 0 : (int)$param;
|
||||
$this->config->company->browse->search['actionURL'] = $this->createLink('company', 'browse', "param=myQueryID&type=bysearch");
|
||||
$this->config->company->browse->search['queryID'] = $queryID;
|
||||
$this->config->company->browse->search['params']['dept']['values'] = array('' => '') + $this->dept->getOptionMenu();
|
||||
$queryID = $type == 'bydept' ? 0 : (int)$param;
|
||||
$actionURL = $this->createLink('company', 'browse', "param=myQueryID&type=bysearch");
|
||||
$this->company->buildSearchForm($queryID, $actionURL);
|
||||
$this->loadModel('search')->setSearchParams($this->config->company->browse->search);
|
||||
|
||||
if($type == 'bydept')
|
||||
{
|
||||
$childDeptIds = $this->dept->getAllChildID($deptID);
|
||||
$users = $this->dept->getUsers($childDeptIds, $pager, $sort);
|
||||
}
|
||||
else
|
||||
{
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->search->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('userQuery', $query->sql);
|
||||
$this->session->set('userForm', $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set('userQuery', ' 1 = 1');
|
||||
}
|
||||
}
|
||||
$users = $this->loadModel('user')->getByQuery($this->session->userQuery, $pager, $sort);
|
||||
}
|
||||
/* Get users. */
|
||||
$users = $this->company->getUsers($type, $queryID, $deptID, $sort, $pager);
|
||||
|
||||
/* Set view. */
|
||||
$this->view->title = $this->lang->company->index . $this->lang->colon . $this->lang->dept->common;
|
||||
$this->view->position[] = $this->lang->dept->common;
|
||||
$this->view->users = $users;
|
||||
|
||||
@@ -9,4 +9,5 @@ function manageContacts()
|
||||
$(function()
|
||||
{
|
||||
setTimeout(function(){fixedTfootAction('#userListForm')}, '100');
|
||||
setTimeout(function(){fixedTheadOfList('#userList')}, '100');
|
||||
})
|
||||
|
||||
@@ -61,6 +61,48 @@ class companyModel extends model
|
||||
return $this->dao->findById((int)$companyID)->from(TABLE_COMPANY)->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get users.
|
||||
*
|
||||
* @param string $type
|
||||
* @param int $queryID
|
||||
* @param int $deptID
|
||||
* @param string $sort
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getUsers($type, $queryID, $deptID, $sort, $pager)
|
||||
{
|
||||
/* Get users. */
|
||||
if($type == 'bydept')
|
||||
{
|
||||
$childDeptIds = $this->loadModel('dept')->getAllChildID($deptID);
|
||||
$users = $this->dept->getUsers($childDeptIds, $pager, $sort);
|
||||
}
|
||||
else
|
||||
{
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('userQuery', $query->sql);
|
||||
$this->session->set('userForm', $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set('userQuery', ' 1 = 1');
|
||||
}
|
||||
}
|
||||
$users = $this->loadModel('user')->getByQuery($this->session->userQuery, $pager, $sort);
|
||||
}
|
||||
|
||||
if($users) return $users;
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a company.
|
||||
*
|
||||
@@ -81,4 +123,19 @@ class companyModel extends model
|
||||
->where('id')->eq($companyID)
|
||||
->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build search form.
|
||||
*
|
||||
* @param int $queryID
|
||||
* @param string $actionURL
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function buildSearchForm($queryID, $actionURL)
|
||||
{
|
||||
$this->config->company->browse->search['actionURL'] = $actionURL;
|
||||
$this->config->company->browse->search['queryID'] = $queryID;
|
||||
$this->config->company->browse->search['params']['dept']['values'] = array('' => '') + $this->loadModel('dept')->getOptionMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,8 +98,8 @@ js::set('confirmDelete', $lang->user->confirmDelete);
|
||||
<td colspan='12'>
|
||||
<div class='table-actions clearfix'>
|
||||
<?php
|
||||
if($canBatchEdit or $canManageContacts) echo "<div class='btn-group'>" . html::selectButton() . '</div>';
|
||||
if($canBatchEdit) echo html::submitButton($lang->edit, 'onclick=batchEdit()', 'btn-default');
|
||||
if($canBatchEdit or $canManageContacts) echo html::selectButton();
|
||||
if($canBatchEdit) echo html::submitButton($lang->edit, 'onclick=batchEdit()', 'btn btn-default');
|
||||
if($canManageContacts) echo html::submitButton($lang->user->contacts->manage, 'onclick=manageContacts()');
|
||||
?>
|
||||
</div>
|
||||
|
||||
1
module/cron/css/common.css
Normal file
1
module/cron/css/common.css
Normal file
@@ -0,0 +1 @@
|
||||
.pdl-15{padding-left:15px !important}
|
||||
@@ -50,3 +50,5 @@ $lang->cron->notice->dom = 'Range : 1-31';
|
||||
$lang->cron->notice->mon = 'Range : 1-12';
|
||||
$lang->cron->notice->dow = 'Range : 0-6';
|
||||
$lang->cron->notice->help = 'Note: if the server is restarted, or that the timing task is not normal, then the timing task has stopped. You need to click the [Open process] button or refresh page after a minute to open the scheduled tasks. If the last run time of first record is changed in cron list, then the task is turned on.';
|
||||
|
||||
$lang->cron->error['rule'] = '"%s" is not a valid value';
|
||||
|
||||
@@ -50,3 +50,5 @@ $lang->cron->notice->dom = '取值范围:1-31';
|
||||
$lang->cron->notice->mon = '取值范围:1-12';
|
||||
$lang->cron->notice->dow = '取值范围:0-6';
|
||||
$lang->cron->notice->help = '注:如果服务器重启,或者发现计划任务没有正常工作,那么计划任务已经停止工作。需要手动点击【创建进程】按钮,或者一分钟后刷新页面,来开启计划任务。如果任务列表中第一条记录的最后执行时间改变,说明任务开启成功。';
|
||||
|
||||
$lang->cron->error['rule'] = '"%s" 填写的不是合法的值';
|
||||
|
||||
@@ -168,10 +168,15 @@ class cronModel extends model
|
||||
->add('lastTime', '0000-00-00 00:00:00')
|
||||
->skipSpecial('m,h,dom,mon,dow,command')
|
||||
->get();
|
||||
$this->dao->insert(TABLE_CRON)->data($cron)
|
||||
->autoCheck()
|
||||
->batchCheck($this->config->cron->create->requiredFields, 'notempty')
|
||||
->exec();
|
||||
|
||||
$checkRule = $this->checkRule($cron);
|
||||
if(!empty($checkRule))
|
||||
{
|
||||
dao::$errors[] = $checkRule;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->dao->insert(TABLE_CRON)->data($cron)->autoCheck()->exec();
|
||||
|
||||
return $this->dao->lastInsertID();
|
||||
}
|
||||
@@ -189,13 +194,36 @@ class cronModel extends model
|
||||
->add('lastTime', '0000-00-00 00:00:00')
|
||||
->skipSpecial('m,h,dom,mon,dow,command')
|
||||
->get();
|
||||
$this->dao->update(TABLE_CRON)->data($cron)
|
||||
->autoCheck()
|
||||
->batchCheck($this->config->cron->create->requiredFields, 'notempty')
|
||||
->where('id')->eq($cronID)->exec();
|
||||
|
||||
$checkRule = $this->checkRule($cron);
|
||||
if(!empty($checkRule))
|
||||
{
|
||||
dao::$errors[] = $checkRule;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_CRON)->data($cron)->autoCheck()->where('id')->eq($cronID)->exec();
|
||||
return dao::isError() ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check cron rule.
|
||||
*
|
||||
* @param object $cron
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function checkRule($cron)
|
||||
{
|
||||
if($cron->m === '' or preg_match('/[^0-9\*\-\/]/', $cron->m)) return sprintf($this->lang->cron->error['rule'], $this->lang->cron->m);
|
||||
if($cron->h === '' or preg_match('/[^0-9\*\-\/]/', $cron->h)) return sprintf($this->lang->cron->error['rule'], $this->lang->cron->h);
|
||||
if($cron->dom === '' or preg_match('/[^0-9\*\-\/]/', $cron->dom))return sprintf($this->lang->cron->error['rule'], $this->lang->cron->dom);
|
||||
if($cron->mon === '' or preg_match('/[^0-9\*\-\/]/', $cron->mon))return sprintf($this->lang->cron->error['rule'], $this->lang->cron->mon);
|
||||
if($cron->dow === '' or preg_match('/[^0-9\*\-\/]/', $cron->dow))return sprintf($this->lang->cron->error['rule'], $this->lang->cron->dow);
|
||||
if(empty($cron->command))return sprintf($this->lang->error->notempty, $this->lang->cron->command);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function markCronStatus($status, $configID = 0)
|
||||
{
|
||||
if($configID)
|
||||
|
||||
@@ -23,27 +23,27 @@
|
||||
<tr>
|
||||
<th class='rowhead w-80px'><?php echo $lang->cron->m;?></th>
|
||||
<td class='w-p20'><?php echo html::input('m', '', "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->m;?></td>
|
||||
<td class='pdl-15'><?php echo $lang->cron->notice->m;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->h;?></th>
|
||||
<td><?php echo html::input('h', '', "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->h;?></td>
|
||||
<td class='pdl-15'><?php echo $lang->cron->notice->h;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->dom;?></th>
|
||||
<td><?php echo html::input('dom', '', "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->dom;?></td>
|
||||
<td class='pdl-15'><?php echo $lang->cron->notice->dom;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->mon;?></th>
|
||||
<td><?php echo html::input('mon', '', "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->mon;?></td>
|
||||
<td class='pdl-15'><?php echo $lang->cron->notice->mon;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->dow;?></th>
|
||||
<td><?php echo html::input('dow', '', "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->dow;?></td>
|
||||
<td class='pdl-15'><?php echo $lang->cron->notice->dow;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->command;?></th>
|
||||
|
||||
@@ -23,27 +23,27 @@
|
||||
<tr>
|
||||
<th class='rowhead w-80px'><?php echo $lang->cron->m;?></th>
|
||||
<td class='w-p20'><?php echo html::input('m', $cron->m, "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->m;?></td>
|
||||
<td class='pdl-15'><?php echo $lang->cron->notice->m;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->h;?></th>
|
||||
<td><?php echo html::input('h', $cron->h, "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->h;?></td>
|
||||
<td class='pdl-15'><?php echo $lang->cron->notice->h;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->dom;?></th>
|
||||
<td><?php echo html::input('dom', $cron->dom, "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->dom;?></td>
|
||||
<td class='pdl-15'><?php echo $lang->cron->notice->dom;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->mon;?></th>
|
||||
<td><?php echo html::input('mon', $cron->mon, "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->mon;?></td>
|
||||
<td class='pdl-15'><?php echo $lang->cron->notice->mon;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->dow;?></th>
|
||||
<td><?php echo html::input('dow', $cron->dow, "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->dow;?></td>
|
||||
<td class='pdl-15'><?php echo $lang->cron->notice->dow;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->command;?></th>
|
||||
|
||||
@@ -76,72 +76,15 @@ class doc extends control
|
||||
/* Append id for secend sort. */
|
||||
$sort = $this->loadModel('common')->appendOrder($orderBy);
|
||||
|
||||
/* Get docs. */
|
||||
$modules = 0;
|
||||
$docs=array();
|
||||
if($browseType == "bymodule")
|
||||
{
|
||||
if($moduleID) $modules = $this->tree->getAllChildID($moduleID);
|
||||
$docs = $this->doc->getDocs($libID, $productID, $projectID, $modules, $sort, $pager);
|
||||
}
|
||||
elseif($browseType == "bysearch")
|
||||
{
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->search->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('docQuery', $query->sql);
|
||||
$this->session->set('docForm', $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set('docQuery', ' 1 = 1');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->docQuery == false) $this->session->set('docQuery', ' 1 = 1');
|
||||
}
|
||||
$docQuery = str_replace("`product` = 'all'", '1', $this->session->docQuery); // Search all producti.
|
||||
$docQuery = str_replace("`project` = 'all'", '1', $docQuery); // Search all project.
|
||||
$docs = $this->dao->select('*')->from(TABLE_DOC)->where($docQuery)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->orderBy($sort)->page($pager)->fetchAll();
|
||||
}
|
||||
/* Get docs by browse type. */
|
||||
$docs = $this->doc->getDocsByBrowseType($productID, $projectID, $browseType, $libID, $queryID, $moduleID, $sort, $pager);
|
||||
|
||||
/* Get the tree menu. */
|
||||
if($libID == 'product')
|
||||
{
|
||||
$moduleTree = $this->tree->getProductDocTreeMenu();
|
||||
}
|
||||
elseif($libID == 'project')
|
||||
{
|
||||
$moduleTree = $this->tree->getProjectDocTreeMenu();
|
||||
}
|
||||
else
|
||||
{
|
||||
$moduleTree = $this->tree->getTreeMenu($libID, $viewType = 'customdoc', $startModuleID = 0, array('treeModel', 'createDocLink'));
|
||||
}
|
||||
$moduleTree = $this->doc->getDocTreeMenu($libID);
|
||||
|
||||
/* Build the search form. */
|
||||
$this->config->doc->search['actionURL'] = $this->createLink('doc', 'browse', "libID=$libID&moduleID=$moduleID&procuctID=$productID&projectID=$projectID&browseType=bySearch&queryID=myQueryID");
|
||||
$this->config->doc->search['queryID'] = $queryID;
|
||||
$this->config->doc->search['params']['product']['values'] = array(''=>'') + $this->product->getPairs('nocode') + array('all'=>$this->lang->doc->allProduct);
|
||||
$this->config->doc->search['params']['project']['values'] = array(''=>'') + $this->project->getPairs('nocode') + array('all'=>$this->lang->doc->allProject);
|
||||
$this->config->doc->search['params']['lib']['values'] = array(''=>'') + $this->libs;
|
||||
$this->config->doc->search['params']['type']['values'] = array(''=>'') + $this->config->doc->search['params']['type']['values'];
|
||||
|
||||
/* Get the modules. */
|
||||
if($libID == 'product' or $libID == 'project')
|
||||
{
|
||||
$moduleOptionMenu = $this->tree->getOptionMenu(0, $libID . 'doc', $startModuleID = 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$moduleOptionMenu = $this->tree->getOptionMenu($libID, 'customdoc', $startModuleID = 0);
|
||||
}
|
||||
$this->config->doc->search['params']['module']['values'] = $moduleOptionMenu;
|
||||
$actionURL = $this->createLink('doc', 'browse', "libID=$libID&moduleID=$moduleID&procuctID=$productID&projectID=$projectID&browseType=bySearch&queryID=myQueryID");
|
||||
$this->doc->buildSearchForm($libID, $this->libs, $queryID, $actionURL);
|
||||
$this->search->setSearchParams($this->config->doc->search);
|
||||
|
||||
$this->view->libID = $libID;
|
||||
|
||||
@@ -106,6 +106,57 @@ class docModel extends model
|
||||
if(!dao::isError()) return common::createChanges($oldLib, $lib);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get docs by browse type.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $projectID
|
||||
* @param string $browseType
|
||||
* @param string $libID
|
||||
* @param int $queryID
|
||||
* @param int $moduleID
|
||||
* @param string $sort
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDocsByBrowseType($productID, $projectID, $browseType, $libID, $queryID, $moduleID, $sort, $pager)
|
||||
{
|
||||
if($browseType == "bymodule")
|
||||
{
|
||||
$modules = 0;
|
||||
if($moduleID) $modules = $this->loadModel('tree')->getAllChildId($moduleID);
|
||||
$docs = $this->getDocs($libID, $productID, $projectID, $modules, $sort, $pager);
|
||||
}
|
||||
elseif($browseType == "bysearch")
|
||||
{
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('docQuery', $query->sql);
|
||||
$this->session->set('docForm', $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set('docQuery', ' 1 = 1');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->docQuery == false) $this->session->set('docQuery', ' 1 = 1');
|
||||
}
|
||||
$docQuery = str_replace("`product` = 'all'", '1', $this->session->docQuery); // Search all producti.
|
||||
$docQuery = str_replace("`project` = 'all'", '1', $docQuery); // Search all project.
|
||||
$docs = $this->dao->select('*')->from(TABLE_DOC)->where($docQuery)->andWhere('deleted')->eq(0)->orderBy($sort)->page($pager)->fetchAll();
|
||||
}
|
||||
|
||||
if($docs) return $docs;
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get docs.
|
||||
*
|
||||
@@ -243,6 +294,37 @@ class docModel extends model
|
||||
->exec();
|
||||
if(!dao::isError()) return common::createChanges($oldDoc, $doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build search form.
|
||||
*
|
||||
* @param string $libID
|
||||
* @param array $libs
|
||||
* @param int $queryID
|
||||
* @param string $actionURL
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function buildSearchForm($libID, $libs, $queryID, $actionURL)
|
||||
{
|
||||
$this->config->doc->search['actionURL'] = $actionURL;
|
||||
$this->config->doc->search['queryID'] = $queryID;
|
||||
$this->config->doc->search['params']['product']['values'] = array(''=>'') + $this->loadModel('product')->getPairs('nocode') + array('all'=>$this->lang->doc->allProduct);
|
||||
$this->config->doc->search['params']['project']['values'] = array(''=>'') + $this->loadModel('project')->getPairs('nocode') + array('all'=>$this->lang->doc->allProject);
|
||||
$this->config->doc->search['params']['lib']['values'] = array(''=>'') + $libs;
|
||||
$this->config->doc->search['params']['type']['values'] = array(''=>'') + $this->config->doc->search['params']['type']['values'];
|
||||
|
||||
/* Get the modules. */
|
||||
if($libID == 'product' or $libID == 'project')
|
||||
{
|
||||
$moduleOptionMenu = $this->loadModel('tree')->getOptionMenu(0, $libID . 'doc', $startModuleID = 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($libID, 'customdoc', $startModuleID = 0);
|
||||
}
|
||||
$this->config->doc->search['params']['module']['values'] = $moduleOptionMenu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get docs of a product.
|
||||
@@ -296,6 +378,31 @@ class docModel extends model
|
||||
return $this->dao->findByType('projectdoc')->from(TABLE_MODULE)->andWhere('type')->eq('projectdoc')->fetchPairs('id', 'name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get doc tree menu.
|
||||
*
|
||||
* @param string $libID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDocTreeMenu($libID)
|
||||
{
|
||||
if($libID == 'product')
|
||||
{
|
||||
$moduleTree = $this->loadModel('tree')->getProductDocTreeMenu();
|
||||
}
|
||||
elseif($libID == 'project')
|
||||
{
|
||||
$moduleTree = $this->loadModel('tree')->getProjectDocTreeMenu();
|
||||
}
|
||||
else
|
||||
{
|
||||
$moduleTree = $this->loadModel('tree')->getTreeMenu($libID, $viewType = 'customdoc', $startModuleID = 0, array('treeModel', 'createDocLink'));
|
||||
}
|
||||
|
||||
return $moduleTree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract css styles for tables created in kindeditor.
|
||||
*
|
||||
|
||||
@@ -11,7 +11,7 @@ table.fileBox td {padding: 0!important}
|
||||
$fileRow = <<<EOT
|
||||
<table class='fileBox' id='fileBox\$i'>
|
||||
<tr>
|
||||
<td class='w-p45'><div class='form-control file-wrapper'><input type='file' name='files[]' class='fileControl' tabindex='-1' onchange='checkSize(this)'/></div></td>
|
||||
<td class='w-p45'><div class='form-control file-wrapper'><input type='file' name='files[]' class='fileControl' tabindex='-1' onchange='checkSize(this)'/></div></td>
|
||||
<td class=''><input type='text' name='labels[]' class='form-control' placeholder='{$lang->file->label}' tabindex='-1' /></td>
|
||||
<td class='w-30px'><a href='javascript:void();' onclick='addFile(this)' class='btn btn-block'><i class='icon-plus'></i></a></td>
|
||||
<td class='w-30px'><a href='javascript:void();' onclick='delFile(this)' class='btn btn-block'><i class='icon-remove'></i></a></td>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
<?php
|
||||
if(count($queueList))
|
||||
{
|
||||
echo "<div class='btn-group'>" . html::selectButton() . '</div>';
|
||||
echo html::selectButton();
|
||||
if(common::hasPriv('mail', 'batchDelete')) echo html::submitButton($lang->delete);
|
||||
}
|
||||
$pager->show();
|
||||
|
||||
@@ -152,4 +152,38 @@ class misc extends control
|
||||
$this->app->loadClass('qrcode');
|
||||
QRcode::png($loginAPI . $session, false, 4, 9);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and repair database table.
|
||||
*
|
||||
* @param string $type
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function checkTable($type = 'check')
|
||||
{
|
||||
if($type != 'check' and $type != 'repair') die();
|
||||
if(!isset($_SESSION['checkFileName']))
|
||||
{
|
||||
$checkFileName = $this->app->getBasePath() . 'www' . DS . uniqid('repair_') . '.txt';
|
||||
$this->session->set('checkFileName', $checkFileName);
|
||||
}
|
||||
|
||||
$checkFileName = $this->session->checkFileName;
|
||||
$this->view->title = $this->lang->misc->checkTable;
|
||||
|
||||
$status = '';
|
||||
if(!file_exists($checkFileName) or (time() - filemtime($checkFileName)) > 60 * 10) $status = 'createFile';
|
||||
|
||||
if($status == 'createFile')
|
||||
{
|
||||
$this->app->loadLang('user');
|
||||
$this->view->status = $status;
|
||||
die($this->display());
|
||||
}
|
||||
|
||||
$this->view->tables = $this->misc->getTableAndStatus($type);
|
||||
$this->view->status = 'check';
|
||||
$this->display();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,11 @@ $lang->misc->zentao->service['install'] = 'Install service';
|
||||
$lang->misc->zentao->service['fixissue'] = 'Issue support';
|
||||
$lang->misc->zentao->service['servicemore']= 'More...';
|
||||
|
||||
$lang->misc->mobile = "Mobile access";
|
||||
$lang->misc->noGDLib = "Please visit:<strong>%s</strong>.";
|
||||
$lang->misc->copyright = "© 2009-2015 <a href='http://www.cnezsoft.com' target='_blank'>Nature EasySoft Network Tecnology Co.ltd, QingDao, China</a> 4006-8899-23 <a href='mailto:co@zentao.net'>co@zentao.net</a>";
|
||||
$lang->misc->mobile = "Mobile access";
|
||||
$lang->misc->noGDLib = "Please visit:<strong>%s</strong>.";
|
||||
$lang->misc->copyright = "© 2009-2015 <a href='http://www.cnezsoft.com' target='_blank'>Nature EasySoft Network Tecnology Co.ltd, QingDao, China</a> 4006-8899-23 <a href='mailto:co@zentao.net'>co@zentao.net</a>";
|
||||
$lang->misc->checkTable = "Check and repair table";
|
||||
$lang->misc->needRepair = "Repair Table";
|
||||
$lang->misc->repairTable = "The database table can cause of damage because of power failure, need to check and repair!!";
|
||||
$lang->misc->tableName = "Table name";
|
||||
$lang->misc->tableStatus = "Table status";
|
||||
|
||||
@@ -51,6 +51,11 @@ $lang->misc->zentao->service['install'] = '禅道安装服务';
|
||||
$lang->misc->zentao->service['fixissue'] = '禅道问题解决';
|
||||
$lang->misc->zentao->service['servicemore']= '更多服务...';
|
||||
|
||||
$lang->misc->mobile = "手机访问";
|
||||
$lang->misc->noGDLib = "请用手机浏览器访问:<strong>%s</strong>";
|
||||
$lang->misc->copyright = "© 2009 - 2015 <a href='http://www.cnezsoft.com' target='_blank'>青岛易软天创网络科技有限公司</a> 电话:4006-8899-23 Email:<a href='mailto:co@zentao.net'>co@zentao.net</a> QQ:1492153927";
|
||||
$lang->misc->mobile = "手机访问";
|
||||
$lang->misc->noGDLib = "请用手机浏览器访问:<strong>%s</strong>";
|
||||
$lang->misc->copyright = "© 2009 - 2015 <a href='http://www.cnezsoft.com' target='_blank'>青岛易软天创网络科技有限公司</a> 电话:4006-8899-23 Email:<a href='mailto:co@zentao.net'>co@zentao.net</a> QQ:1492153927";
|
||||
$lang->misc->checkTable = "检查修复数据表";
|
||||
$lang->misc->needRepair = "修复表";
|
||||
$lang->misc->repairTable = "数据库表可以因为断电原因损坏,需要检查修复!!";
|
||||
$lang->misc->tableName = "表名";
|
||||
$lang->misc->tableStatus = "状态";
|
||||
|
||||
@@ -17,4 +17,29 @@ class miscModel extends model
|
||||
{
|
||||
return 'hello world from hello()<br />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table and status.
|
||||
*
|
||||
* @param string $type
|
||||
* @access public
|
||||
* @return array|false
|
||||
*/
|
||||
public function getTableAndStatus($type = 'check')
|
||||
{
|
||||
if($type != 'check' and $type != 'repair') return false;
|
||||
$tables = array();
|
||||
$stmt = $this->dao->query("show full tables");
|
||||
while($table = $stmt->fetch(PDO::FETCH_ASSOC))
|
||||
{
|
||||
$tableName = $table["Tables_in_{$this->config->db->name}"];
|
||||
$tableType = strtolower($table['Table_type']);
|
||||
if($tableType == 'base table')
|
||||
{
|
||||
$tableStatus = $this->dao->query("$type table $tableName")->fetch();
|
||||
$tables[$tableName] = strtolower($tableStatus->Msg_text);
|
||||
}
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
}
|
||||
|
||||
50
module/misc/view/checktable.html.php
Normal file
50
module/misc/view/checktable.html.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* The reset view file of user module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package user
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.lite.html.php';?>
|
||||
<div class='alert alert-info'><strong><?php echo $lang->misc->repairTable;?></strong></div>
|
||||
<div class='container mw-700px'>
|
||||
<?php if($status == 'createFile'):?>
|
||||
<div class='panel-body'>
|
||||
<?php printf($lang->user->noticeResetFile, $this->session->checkFileName);?>
|
||||
</div>
|
||||
<p><?php echo html::a(inlink('checkTable'), $this->lang->refresh, '', "class='btn'")?></p>
|
||||
<?php elseif($status == 'check'):?>
|
||||
<div class='panel'>
|
||||
<table class='table table-form'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo $lang->misc->tableName?></th>
|
||||
<th><?php echo $lang->misc->tableStatus?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $needRepair = false;?>
|
||||
<?php foreach($tables as $tableName => $tableStatus):?>
|
||||
<?php if($tableStatus != 'ok') $needRepair = true;?>
|
||||
<tr>
|
||||
<td><?php echo $tableName;?></td>
|
||||
<td><span style='color:<?php echo $tableStatus == 'ok' ? 'green' : 'red'?>'><?php echo $tableStatus;?></span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<?php endforeach;?>
|
||||
<?php if($needRepair):?>
|
||||
<tfoot>
|
||||
<tr><td class='text-center' colspan='2'><?php echo html::a(inlink('checkTable', "type=repair"), $lang->misc->needRepair, '', "class='btn btn-primary'")?></td></tr>
|
||||
</tfoot>
|
||||
<?php endif;?>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.lite.html.php';?>
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
<td colspan='10'>
|
||||
<?php if($bugs and $canBatchEdit):?>
|
||||
<div class='table-actions clearfix'>
|
||||
<?php echo "<div class='btn-group'>" . html::selectButton() . '</div>' . html::submitButton($lang->edit, '', '');?>
|
||||
<?php echo html::selectButton() . html::submitButton($lang->edit, '', '');?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<?php $pager->show();?>
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><?php echo html::submitButton('', '', 'btn-primary') . html::backButton();?></td>
|
||||
<td><?php echo html::submitButton() . html::backButton();?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
</tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
<div class='text-center'><?php echo html::submitButton('', '', 'btn-primary') . ' ' . html::backButton();?></div>
|
||||
<div class='text-center'><?php echo html::submitButton() . ' ' . html::backButton();?></div>
|
||||
</form>
|
||||
</div>
|
||||
<?php js::set('passwordStrengthList', $lang->user->passwordStrengthList)?>
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
<?php
|
||||
if(count($stories))
|
||||
{
|
||||
if($canBatchEdit or $canBatchRun) echo "<div class='btn-group'>" . html::selectButton() . '</div>';
|
||||
if($canBatchEdit or $canBatchRun) echo html::selectButton();
|
||||
|
||||
if($canBatchEdit)
|
||||
{
|
||||
|
||||
@@ -55,9 +55,9 @@
|
||||
<td><span class='<?php echo 'pri' . zget($lang->task->priList, $task->pri, $task->pri);?>'><?php echo zget($lang->task->priList, $task->pri, $task->pri);?></span></td>
|
||||
<td class='nobr text-left'><?php echo html::a($this->createLink('project', 'browse', "projectid=$task->projectID"), $task->projectName);?></td>
|
||||
<td class='text-left nobr'><?php echo html::a($this->createLink('task', 'view', "taskID=$task->id"), $task->name);?></td>
|
||||
<td><?php echo $users[$task->openedBy];?></td>
|
||||
<td><?php echo $users[$task->assignedTo];?></td>
|
||||
<td><?php echo $users[$task->finishedBy];?></td>
|
||||
<td><?php echo zget($users, $task->openedBy);?></td>
|
||||
<td><?php echo zget($users, $task->assignedTo);?></td>
|
||||
<td><?php echo zget($users, $task->finishedBy);?></td>
|
||||
<td><?php echo $task->estimate;?></td>
|
||||
<td><?php echo $task->consumed;?></td>
|
||||
<td><?php echo $task->left;?></td>
|
||||
@@ -82,7 +82,7 @@
|
||||
<?php if(count($tasks)):?>
|
||||
<div class='table-actions clearfix'>
|
||||
<?php
|
||||
if($canBatchEdit or $canBatchClose) echo "<div class='btn-group'>" . html::selectButton() . '</div>';
|
||||
if($canBatchEdit or $canBatchClose) echo html::selectButton();
|
||||
echo "<div class='btn-group'>";
|
||||
if($canBatchEdit)
|
||||
{
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
<?php if($cases):?>
|
||||
<div class='table-actions clearfix'>
|
||||
<?php
|
||||
if($canBatchEdit or $canBatchRun) echo "<div class='btn-group'>" . html::selectButton() . '</div>';
|
||||
if($canBatchEdit or $canBatchRun) echo html::selectButton();
|
||||
if($canBatchEdit)
|
||||
{
|
||||
$actionLink = $this->createLink('testcase', 'batchEdit');
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
<?php
|
||||
if(common::hasPriv('todo', 'batchEdit') or (common::hasPriv('todo', 'import2Today') and $importFuture))
|
||||
{
|
||||
echo "<div class='btn-group'>" . html::selectButton() . '</div>';
|
||||
echo html::selectButton();
|
||||
}
|
||||
echo "<div class='btn-group'>";
|
||||
if(common::hasPriv('todo', 'batchEdit'))
|
||||
|
||||
@@ -117,7 +117,7 @@ class product extends control
|
||||
|
||||
/* Set product, module and query. */
|
||||
$productID = $this->product->saveState($productID, $this->products);
|
||||
if($branch === '') $branch = $this->session->branch;
|
||||
$branch = ($branch === '') ? $this->session->branch : $branch;
|
||||
$moduleID = ($browseType == 'bymodule') ? (int)$param : 0;
|
||||
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
|
||||
|
||||
@@ -131,61 +131,26 @@ class product extends control
|
||||
/* Append id for secend sort. */
|
||||
$sort = $this->loadModel('common')->appendOrder($orderBy);
|
||||
|
||||
/* Set header and position. */
|
||||
$this->view->title = $this->products[$productID]. $this->lang->colon . $this->lang->product->browse;
|
||||
$this->view->position[] = $this->products[$productID];
|
||||
$this->view->position[] = $this->lang->product->browse;
|
||||
|
||||
/* Load pager. */
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
if($this->app->getViewType() == 'mhtml') $recPerPage = 10;
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
/* Get stories. */
|
||||
$stories = array();
|
||||
if($browseType == 'unclosed')
|
||||
{
|
||||
$unclosedStatus = $this->lang->story->statusList;
|
||||
unset($unclosedStatus['closed']);
|
||||
$stories = $this->story->getProductStories($productID, $branch, 0, array_keys($unclosedStatus), $sort, $pager);
|
||||
}
|
||||
if($browseType == 'allstory') $stories = $this->story->getProductStories($productID, $branch, 0, 'all', $sort, $pager);
|
||||
if($browseType == 'bymodule') $stories = $this->story->getProductStories($productID, $branch, $this->tree->getAllChildID($moduleID), 'all', $sort, $pager);
|
||||
if($browseType == 'bysearch') $stories = $this->story->getBySearch($productID, $queryID, $sort, $pager, '', $branch);
|
||||
if($browseType == 'assignedtome')$stories = $this->story->getByAssignedTo($productID, $branch, $this->app->user->account, $sort, $pager);
|
||||
if($browseType == 'openedbyme') $stories = $this->story->getByOpenedBy($productID, $branch, $this->app->user->account, $sort, $pager);
|
||||
if($browseType == 'reviewedbyme')$stories = $this->story->getByReviewedBy($productID, $branch, $this->app->user->account, $sort, $pager);
|
||||
if($browseType == 'closedbyme') $stories = $this->story->getByClosedBy($productID, $branch, $this->app->user->account, $sort, $pager);
|
||||
if($browseType == 'draftstory') $stories = $this->story->getByStatus($productID, $branch, 'draft', $sort, $pager);
|
||||
if($browseType == 'activestory') $stories = $this->story->getByStatus($productID, $branch, 'active', $sort, $pager);
|
||||
if($browseType == 'changedstory')$stories = $this->story->getByStatus($productID, $branch, 'changed', $sort, $pager);
|
||||
if($browseType == 'willclose') $stories = $this->story->getWillClose($productID, $branch, $sort, $pager);
|
||||
if($browseType == 'closedstory') $stories = $this->story->getByStatus($productID, $branch, 'closed', $sort, $pager);
|
||||
$stories = $this->product->getStories($productID, $branch, $browseType, $queryID, $moduleID, $sort, $pager);
|
||||
|
||||
/* Process the sql, get the conditon partion, save it to session. */
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story');
|
||||
|
||||
/* Build search form. */
|
||||
$this->config->product->search['actionURL'] = $this->createLink('product', 'browse', "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID");
|
||||
$this->config->product->search['queryID'] = $queryID;
|
||||
$this->config->product->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairs($productID);
|
||||
$this->config->product->search['params']['product']['values'] = array($productID => $this->products[$productID], 'all' => $this->lang->product->allProduct);
|
||||
$this->config->product->search['params']['module']['values'] = $this->tree->getOptionMenu($productID, $viewType = 'story', $startModuleID = 0);
|
||||
if($this->session->currentProductType == 'normal')
|
||||
{
|
||||
unset($this->config->product->search['fields']['branch']);
|
||||
unset($this->config->product->search['params']['branch']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->config->product->search['fields']['branch'] = $this->lang->product->branch;
|
||||
$this->config->product->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty');
|
||||
}
|
||||
$actionURL = $this->createLink('product', 'browse', "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID");
|
||||
$this->product->buildSearchForm($productID, $this->products, $queryID, $actionURL);
|
||||
$this->loadModel('search')->setSearchParams($this->config->product->search);
|
||||
|
||||
$storyIdList = array();
|
||||
foreach($stories as $story) $storyIdList[$story->id] = $story->id;
|
||||
|
||||
/* Set view. */
|
||||
$this->view->title = $this->products[$productID]. $this->lang->colon . $this->lang->product->browse;
|
||||
$this->view->position[] = $this->products[$productID];
|
||||
$this->view->position[] = $this->lang->product->browse;
|
||||
$this->view->productID = $productID;
|
||||
$this->view->productName = $this->products[$productID];
|
||||
$this->view->moduleID = $moduleID;
|
||||
@@ -201,7 +166,7 @@ class product extends control
|
||||
$this->view->moduleID = $moduleID;
|
||||
$this->view->branch = $branch;
|
||||
$this->view->branches = $this->loadModel('branch')->getPairs($productID);
|
||||
$this->view->storyStages = $this->story->getStoryStages($storyIdList);
|
||||
$this->view->storyStages = $this->product->getStoryStages($stories);
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,4 +21,5 @@ $(function()
|
||||
$('.popoverStage').mouseover(function(){$(this).popover('show')});
|
||||
$('.popoverStage').mouseout(function(){$(this).popover('hide')});
|
||||
setTimeout(function(){fixedTfootAction('#productStoryForm')}, 100);
|
||||
setTimeout(function(){fixedTheadOfList('#storyList')}, 100);
|
||||
})
|
||||
|
||||
@@ -342,6 +342,93 @@ class productModel extends model
|
||||
if(!dao::isError()) return common::createChanges($oldProduct, $product);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stories.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $branch
|
||||
* @param string $browseType
|
||||
* @param int $queryID
|
||||
* @param int $moduleID
|
||||
* @param string $sort
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getStories($productID, $branch, $browseType, $queryID, $moduleID, $sort, $pager)
|
||||
{
|
||||
$this->loadModel('story');
|
||||
|
||||
/* Get stories by browseType. */
|
||||
if($browseType == 'unclosed')
|
||||
{
|
||||
$unclosedStatus = $this->lang->story->statusList;
|
||||
unset($unclosedStatus['closed']);
|
||||
$stories = $this->story->getProductStories($productID, $branch, 0, array_keys($unclosedStatus), $sort, $pager);
|
||||
}
|
||||
if($browseType == 'allstory') $stories = $this->story->getProductStories($productID, $branch, 0, 'all', $sort, $pager);
|
||||
if($browseType == 'bymodule') $stories = $this->story->getProductStories($productID, $branch, $this->loadModel('tree')->getAllChildID($moduleID), 'all', $sort, $pager);
|
||||
if($browseType == 'bysearch') $stories = $this->story->getBySearch($productID, $queryID, $sort, $pager, '', $branch);
|
||||
if($browseType == 'assignedtome') $stories = $this->story->getByAssignedTo($productID, $branch, $this->app->user->account, $sort, $pager);
|
||||
if($browseType == 'openedbyme') $stories = $this->story->getByOpenedBy($productID, $branch, $this->app->user->account, $sort, $pager);
|
||||
if($browseType == 'reviewedbyme') $stories = $this->story->getByReviewedBy($productID, $branch, $this->app->user->account, $sort, $pager);
|
||||
if($browseType == 'closedbyme') $stories = $this->story->getByClosedBy($productID, $branch, $this->app->user->account, $sort, $pager);
|
||||
if($browseType == 'draftstory') $stories = $this->story->getByStatus($productID, $branch, 'draft', $sort, $pager);
|
||||
if($browseType == 'activestory') $stories = $this->story->getByStatus($productID, $branch, 'active', $sort, $pager);
|
||||
if($browseType == 'changedstory') $stories = $this->story->getByStatus($productID, $branch, 'changed', $sort, $pager);
|
||||
if($browseType == 'willclose') $stories = $this->story->getWillClose($productID, $branch, $sort, $pager);
|
||||
if($browseType == 'closedstory') $stories = $this->story->getByStatus($productID, $branch, 'closed', $sort, $pager);
|
||||
|
||||
if($stories) return $stories;
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get story stages.
|
||||
*
|
||||
* @param array $stories.
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getStoryStages($stories)
|
||||
{
|
||||
/* Set story id list. */
|
||||
$storyIdList = array();
|
||||
foreach($stories as $story) $storyIdList[$story->id] = $story->id;
|
||||
|
||||
return $this->loadModel('story')->getStoryStages($storyIdList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build search form.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param array $products
|
||||
* @param int $queryID
|
||||
* @param int $actionURL
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function buildSearchForm($productID, $products, $queryID, $actionURL)
|
||||
{
|
||||
$this->config->product->search['actionURL'] = $actionURL;
|
||||
$this->config->product->search['queryID'] = $queryID;
|
||||
$this->config->product->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairs($productID);
|
||||
$this->config->product->search['params']['product']['values'] = array($productID => $products[$productID], 'all' => $this->lang->product->allProduct);
|
||||
$this->config->product->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($productID, $viewType = 'story', $startModuleID = 0);
|
||||
if($this->session->currentProductType == 'normal')
|
||||
{
|
||||
unset($this->config->product->search['fields']['branch']);
|
||||
unset($this->config->product->search['params']['branch']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->config->product->search['fields']['branch'] = $this->lang->product->branch;
|
||||
$this->config->product->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get projects of a product in pairs.
|
||||
*
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
<td colspan='11'>
|
||||
<div class='table-actions clearfix'>
|
||||
<?php if(count($stories)):?>
|
||||
<div class='btn-group'><?php echo html::selectButton();?></div>
|
||||
<?php echo html::selectButton();?>
|
||||
<?php
|
||||
$canBatchEdit = common::hasPriv('story', 'batchEdit');
|
||||
$disabled = $canBatchEdit ? '' : "disabled='disabled'";
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
<td colspan='<?php echo $canOrder ? 12 : 11?>'>
|
||||
<div class='table-actions clearfix'>
|
||||
<?php if($canBatchEdit and !empty($productStats)):?>
|
||||
<?php echo "<div class='btn-group'>" . html::selectButton() . '</div>';?>
|
||||
<?php echo html::selectButton();?>
|
||||
<?php echo html::submitButton($lang->product->batchEdit, '', '');?>
|
||||
<?php endif;?>
|
||||
<?php if(!$canOrder and common::hasPriv('product', 'updateOrder')) echo html::a(inlink('index', "locate=no&productID=$productID&status=$status&order=order_desc&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"), $lang->product->updateOrder, '' , "class='btn'");?>
|
||||
|
||||
@@ -71,15 +71,15 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->product->PO;?></th>
|
||||
<td><?php echo $users[$product->PO];?></td>
|
||||
<td><?php echo zget($users, $product->PO);?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->product->QD;?></th>
|
||||
<td><?php echo $users[$product->QD];?></td>
|
||||
<td><?php echo zget($users, $product->QD);?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->product->RD;?></th>
|
||||
<td><?php echo $users[$product->RD];?></td>
|
||||
<td><?php echo zget($users, $product->RD);?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->product->type;?></th>
|
||||
@@ -104,7 +104,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->openedBy?></th>
|
||||
<td><?php echo $users[$product->createdBy];?></td>
|
||||
<td><?php echo zget($users, $product->createdBy);?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->openedDate?></th>
|
||||
|
||||
@@ -43,8 +43,8 @@ include '../../common/view/tablesorter.html.php';
|
||||
<td><span class='<?php echo 'pri' . zget($lang->story->priList, $story->pri, $story->pri);?>'><?php echo zget($lang->story->priList, $story->pri, $story->pri)?></span></td>
|
||||
<td><?php echo $story->planTitle;?></td>
|
||||
<td class='text-left nobr'><?php echo html::a($this->createLink('story', 'view', "storyID=$story->id"), $story->title);?></td>
|
||||
<td><?php echo $users[$story->openedBy];?></td>
|
||||
<td><?php echo $users[$story->assignedTo];?></td>
|
||||
<td><?php echo zget($users, $story->openedBy);?></td>
|
||||
<td><?php echo zget($users, $story->assignedTo);?></td>
|
||||
<td><?php echo $story->estimate;?></td>
|
||||
<td class='story-<?php echo $story->status?>'><?php echo $lang->story->statusList[$story->status];?></td>
|
||||
<td><?php echo $lang->story->stageList[$story->stage];?></td>
|
||||
|
||||
@@ -100,8 +100,8 @@
|
||||
</td>
|
||||
<td><span class='<?php echo 'pri' . zget($lang->story->priList, $story->pri, $story->pri)?>'><?php echo zget($lang->story->priList, $story->pri, $story->pri);?></span></td>
|
||||
<td class='text-left nobr'><?php echo html::a($viewLink , $story->title);?></td>
|
||||
<td><?php echo $users[$story->openedBy];?></td>
|
||||
<td><?php echo $users[$story->assignedTo];?></td>
|
||||
<td><?php echo zget($users, $story->openedBy);?></td>
|
||||
<td><?php echo zget($users, $story->assignedTo);?></td>
|
||||
<td><?php echo $story->estimate;?></td>
|
||||
<td class='story-<?php echo $story->status?>'><?php echo $lang->story->statusList[$story->status];?></td>
|
||||
<td><?php echo $lang->story->stageList[$story->stage];?></td>
|
||||
@@ -124,7 +124,7 @@
|
||||
<?php
|
||||
if(count($planStories) and ($canBatchUnlink or $canBatchChangePlan))
|
||||
{
|
||||
echo "<div class='btn-group'>" . html::selectButton() . '</div>';
|
||||
echo html::selectButton();
|
||||
echo "<div class='btn-group dropup'>";
|
||||
$actionLink = inlink('batchUnlinkStory', "planID=$plan->id&orderBy=$orderBy");
|
||||
echo html::commonButton($lang->productplan->unlinkStory, ($canBatchUnlink ? '' : 'disabled') . "onclick=\"setFormAction('$actionLink', '', this)\"");
|
||||
@@ -195,8 +195,8 @@
|
||||
</td>
|
||||
<td><span class='<?php echo 'pri' . zget($lang->bug->priList, $bug->pri, $bug->pri)?>'><?php echo zget($lang->bug->priList, $bug->pri, $bug->pri);?></span></td>
|
||||
<td class='text-left nobr'><?php echo html::a($this->createLink('bug', 'view', "bugID=$bug->id"), $bug->title);?></td>
|
||||
<td><?php echo $users[$bug->openedBy];?></td>
|
||||
<td><?php echo $users[$bug->assignedTo];?></td>
|
||||
<td><?php echo zget($users, $bug->openedBy);?></td>
|
||||
<td><?php echo zget($users, $bug->assignedTo);?></td>
|
||||
<td class='bug-<?php echo $bug->status?>'><?php echo $lang->bug->statusList[$bug->status];?></td>
|
||||
<td>
|
||||
<?php
|
||||
@@ -217,7 +217,7 @@
|
||||
<?php
|
||||
if(count($planBugs) and $canBatchUnlink)
|
||||
{
|
||||
echo "<div class='btn-group'>" . html::selectButton() . '</div>';
|
||||
echo html::selectButton();
|
||||
echo html::submitButton($lang->productplan->batchUnlink);
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -160,65 +160,12 @@ class project extends control
|
||||
if($this->app->getViewType() == 'mhtml') $recPerPage = 10;
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$tasks = array();
|
||||
if($status == 'byProduct')
|
||||
{
|
||||
$modules = $this->tree->getProjectModule($projectID, $productID);
|
||||
$tasks = $this->task->getTasksByModule($projectID, $modules, $sort, $pager);
|
||||
}
|
||||
elseif($status == 'byModule')
|
||||
{
|
||||
$tasks = $this->task->getTasksByModule($projectID, $this->tree->getAllChildID($moduleID), $sort, $pager);
|
||||
}
|
||||
elseif($browseType != "bysearch")
|
||||
{
|
||||
$qureyStatus = $status == 'byProject' ? 'all' : $status;
|
||||
if($qureyStatus == 'unclosed')
|
||||
{
|
||||
$qureyStatus = $this->lang->task->statusList;
|
||||
unset($qureyStatus['closed']);
|
||||
$qureyStatus = array_keys($qureyStatus);
|
||||
}
|
||||
$tasks = $this->task->getProjectTasks($projectID, $qureyStatus, $sort, $pager);
|
||||
}
|
||||
else
|
||||
{
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->search->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('taskQuery', $query->sql);
|
||||
$this->session->set('taskForm', $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set('taskQuery', ' 1 = 1');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->taskQuery == false) $this->session->set('taskQuery', ' 1 = 1');
|
||||
}
|
||||
|
||||
/* Limit current project when no project. */
|
||||
if(strpos($this->session->taskQuery, "`project` =") === false) $this->session->set('taskQuery', $this->session->taskQuery . " AND `project` = $projectID");
|
||||
if(strpos($this->session->taskQuery, "deleted =") === false) $this->session->set('taskQuery', $this->session->taskQuery . " AND deleted = '0'");
|
||||
|
||||
$projectQuery = "`project`" . helper::dbIN(array_keys($this->projects));
|
||||
$taskQuery = str_replace("`project` = 'all'", $projectQuery, $this->session->taskQuery); // Search all project.
|
||||
$this->session->set('taskQueryCondition', $taskQuery);
|
||||
$this->session->set('taskOnlyCondition', true);
|
||||
$this->session->set('taskOrderBy', $sort);
|
||||
|
||||
$tasks = $this->project->getSearchTasks($taskQuery, $pager, $sort);
|
||||
}
|
||||
/* Get tasks. */
|
||||
$tasks = $this->project->getTasks($productID, $projectID, $this->projects, $status, $browseType, $queryID, $moduleID, $sort, $pager);
|
||||
|
||||
/* Build the search form. */
|
||||
$this->config->project->search['actionURL'] = $this->createLink('project', 'task', "projectID=$projectID&status=bySearch¶m=myQueryID");
|
||||
$this->config->project->search['queryID'] = $queryID;
|
||||
$this->config->project->search['params']['project']['values'] = array(''=>'', $projectID => $this->projects[$projectID], 'all' => $this->lang->project->allProject);
|
||||
$this->config->project->search['params']['module']['values'] = $this->tree->getTaskOptionMenu($projectID, $startModuleID = 0);
|
||||
$actionURL = $this->createLink('project', 'task', "projectID=$projectID&status=bySearch¶m=myQueryID");
|
||||
$this->project->buildSearchForm($projectID, $this->projects, $queryID, $actionURL);
|
||||
$this->search->setSearchParams($this->config->project->search);
|
||||
|
||||
/* team member pairs. */
|
||||
|
||||
@@ -15,4 +15,5 @@ $(document).ready(function()
|
||||
});
|
||||
});
|
||||
fixedTfootAction('#projectBugForm');
|
||||
fixedTheadOfList('#bugList');
|
||||
});
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
$(function(){fixedTfootAction('#projectStoryForm');});
|
||||
$(function(){fixedTheadOfList('#storyList');});
|
||||
|
||||
@@ -3,6 +3,7 @@ $(function()
|
||||
setOuterBox();
|
||||
if(browseType == 'bysearch') ajaxGetSearchForm();
|
||||
setTimeout(function(){fixedTfootAction('#projectTaskForm')}, 100);
|
||||
setTimeout(function(){fixedTheadOfList('#taskList')}, 100);
|
||||
|
||||
$('.assign-search').click(function(e)
|
||||
{
|
||||
|
||||
@@ -726,6 +726,84 @@ class projectModel extends model
|
||||
return $stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tasks.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $projectID
|
||||
* @param array $projects
|
||||
* @param string $status
|
||||
* @param string $browseType
|
||||
* @param int $queryID
|
||||
* @param int $moduleID
|
||||
* @param string $sort
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getTasks($productID, $projectID, $projects, $status, $browseType, $queryID, $moduleID, $sort, $pager)
|
||||
{
|
||||
$this->loadModel('task');
|
||||
|
||||
/* Get tasks. */
|
||||
if($status == 'byProduct')
|
||||
{
|
||||
$modules = $this->loadModel('tree')->getProjectModule($projectID, $productID);
|
||||
$tasks = $this->task->getTasksByModule($projectID, $modules, $sort, $pager);
|
||||
}
|
||||
elseif($status == 'byModule')
|
||||
{
|
||||
$tasks = $this->task->getTasksByModule($projectID, $this->loadModel('tree')->getAllChildID($moduleID), $sort, $pager);
|
||||
}
|
||||
elseif($browseType != "bysearch")
|
||||
{
|
||||
$qureyStatus = $status == 'byProject' ? 'all' : $status;
|
||||
if($qureyStatus == 'unclosed')
|
||||
{
|
||||
$qureyStatus = $this->lang->task->statusList;
|
||||
unset($qureyStatus['closed']);
|
||||
$qureyStatus = array_keys($qureyStatus);
|
||||
}
|
||||
$tasks = $this->task->getProjectTasks($projectID, $qureyStatus, $sort, $pager);
|
||||
}
|
||||
else
|
||||
{
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('taskQuery', $query->sql);
|
||||
$this->session->set('taskForm', $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set('taskQuery', ' 1 = 1');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->taskQuery == false) $this->session->set('taskQuery', ' 1 = 1');
|
||||
}
|
||||
|
||||
/* Limit current project when no project. */
|
||||
if(strpos($this->session->taskQuery, "`project` =") === false) $this->session->set('taskQuery', $this->session->taskQuery . " AND `project` = $projectID");
|
||||
if(strpos($this->session->taskQuery, "deleted =") === false) $this->session->set('taskQuery', $this->session->taskQuery . " AND deleted = '0'");
|
||||
|
||||
$projectQuery = "`project`" . helper::dbIN(array_keys($projects));
|
||||
$taskQuery = str_replace("`project` = 'all'", $projectQuery, $this->session->taskQuery); // Search all project.
|
||||
$this->session->set('taskQueryCondition', $taskQuery);
|
||||
$this->session->set('taskOnlyCondition', true);
|
||||
$this->session->set('taskOrderBy', $sort);
|
||||
|
||||
$tasks = $this->getSearchTasks($taskQuery, $pager, $sort);
|
||||
}
|
||||
|
||||
if($tasks) return $tasks;
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get project by id.
|
||||
*
|
||||
@@ -1679,4 +1757,22 @@ class projectModel extends model
|
||||
->where('project')->eq($projectID)
|
||||
->fetchPairs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build search form.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param array $projects
|
||||
* @param int $queryID
|
||||
* @param string $actionURL
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function buildSearchForm($projectID, $projects, $queryID, $actionURL)
|
||||
{
|
||||
$this->config->project->search['actionURL'] = $actionURL;
|
||||
$this->config->project->search['queryID'] = $queryID;
|
||||
$this->config->project->search['params']['project']['values'] = array(''=>'', $projectID => $projects[$projectID], 'all' => $this->lang->project->allProject);
|
||||
$this->config->project->search['params']['module']['values'] = $this->loadModel('tree')->getTaskOptionMenu($projectID, $startModuleID = 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
$canBatchAssignTo = common::hasPriv('bug', 'batchAssignTo');
|
||||
if(count($bugs))
|
||||
{
|
||||
echo "<div class='btn-group'>" . html::selectButton() . '</div>';
|
||||
echo html::selectButton();
|
||||
if($canBatchAssignTo)
|
||||
{
|
||||
$withSearch = count($memberPairs) > 10;
|
||||
|
||||
@@ -59,7 +59,7 @@ var browseType = '<?php echo $browseType;?>';
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan='8'>
|
||||
<div class='table-actions clearfix'><?php echo "<div class='btn-group'>" . html::selectButton() . '</div>' . html::submitButton($lang->import) . html::backButton();?>
|
||||
<div class='table-actions clearfix'><?php echo html::selectButton() . html::submitButton($lang->import) . html::backButton();?>
|
||||
</div>
|
||||
<?php $pager->show();?>
|
||||
</td>
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
<tr>
|
||||
<td colspan='9'>
|
||||
<div class='table-actions clearfix'>
|
||||
<div class='btn-group'><?php echo html::selectButton();?></div>
|
||||
<?php echo html::selectButton();?>
|
||||
<?php echo html::submitButton($lang->project->importTask);?>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
<td colspan='<?php echo $canOrder ? 12 : 11?>'>
|
||||
<div class='table-actions clearfix'>
|
||||
<?php if($canBatchEdit and !empty($projectStats)):?>
|
||||
<?php echo "<div class='btn-group'>" . html::selectButton() . '</div>';?>
|
||||
<?php echo html::selectButton();?>
|
||||
<?php echo html::submitButton($lang->project->batchEdit);?>
|
||||
<?php endif;?>
|
||||
<?php if(!$canOrder and common::hasPriv('project', 'updateOrder')) echo html::a(inlink('index', "locate=no&status=$status&projectID=$projectID&order=order_desc&productID=$productID&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"), $lang->project->updateOrder, '', "class='btn'");?>
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<div class='table-actions clearfix'>
|
||||
|
||||
<?php
|
||||
if($storyCount) echo "<div class='btn-group'>" . html::selectButton() .'</div>' . html::submitButton();
|
||||
if($storyCount) echo html::selectButton() . html::submitButton();
|
||||
else echo "<div class='text'>" . $lang->project->whyNoStories . '</div>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
<?php
|
||||
if(count($stories))
|
||||
{
|
||||
if($canBatchEdit or $canBatchClose) echo "<div class='btn-group'>" . html::selectButton() . '</div>';
|
||||
if($canBatchEdit or $canBatchClose) echo html::selectButton();
|
||||
|
||||
echo "<div class='btn-group dropup'>";
|
||||
if($canBatchEdit)
|
||||
|
||||
@@ -145,7 +145,7 @@
|
||||
$canBatchAssignTo = common::hasPriv('task', 'batchAssignTo');
|
||||
if(count($tasks))
|
||||
{
|
||||
echo "<div class='btn-group'>" . html::selectButton() . '</div>';
|
||||
echo html::selectButton();
|
||||
|
||||
$actionLink = $this->createLink('task', 'batchEdit', "projectID=$projectID");
|
||||
$misc = $canBatchEdit ? "onclick=\"setFormAction('$actionLink')\"" : "disabled='disabled'";
|
||||
|
||||
@@ -39,7 +39,7 @@ class release extends control
|
||||
public function browse($productID, $branch = 0)
|
||||
{
|
||||
$this->commonAction($productID, $branch);
|
||||
$products = $this->product->getPairs();
|
||||
$products = $this->product->getPairs();
|
||||
$this->session->set('releaseList', $this->app->getURI(true));
|
||||
$this->view->title = $products[$productID] . $this->lang->colon . $this->lang->release->browse;
|
||||
$this->view->position[] = $this->lang->release->browse;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
.tabs{position:relative;}
|
||||
.tabs .nav-tabs{border-bottom:none;}
|
||||
.tabs .nav-tabs>li{margin-bottom:0px;}
|
||||
.tabs .tab-content{padding:0px; border:0px;}
|
||||
.tabs .tab-content .tab-pane #querybox{margin:0px; border-left:1px solid #ddd; border-right:1px solid #ddd;}
|
||||
.tabs .tab-content .tab-pane #querybox form{padding-left:0px;}
|
||||
|
||||
@@ -78,6 +78,19 @@ class search extends control
|
||||
public function deleteQuery($queryID)
|
||||
{
|
||||
$this->dao->delete()->from(TABLE_USERQUERY)->where('id')->eq($queryID)->andWhere('account')->eq($this->app->user->account)->exec();
|
||||
die(js::reload('parent'));
|
||||
$this->ajaxGetQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax get query.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxGetQuery()
|
||||
{
|
||||
$module = $this->session->searchParams['module'];
|
||||
$queries = $this->search->getQueryPairs($module);
|
||||
die(html::select('queryID', $queries, '', 'onchange=executeQuery(this.value) class=form-control'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ function saveQuery()
|
||||
saveQueryLink = createLink('search', 'saveQuery');
|
||||
$.post(saveQueryLink, {title: r, module: module}, function(data)
|
||||
{
|
||||
if(data == 'success') location.reload();
|
||||
if(data == 'success') $('#queryBox').load(createLink('search', 'ajaxGetQuery'));
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -273,7 +273,8 @@ function deleteQuery()
|
||||
{
|
||||
queryID = $('#queryID').val();
|
||||
if(!queryID) return;
|
||||
hiddenwin.location.href = createLink('search', 'deleteQuery', 'queryID=' + queryID);
|
||||
deleteLink = createLink('search', 'deleteQuery', 'queryID=' + queryID);
|
||||
$('#queryBox').load(deleteLink);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -401,11 +402,11 @@ foreach($fieldParams as $fieldName => $param)
|
||||
echo html::hidden('actionURL', $actionURL);
|
||||
echo html::hidden('groupItems', $groupItems);
|
||||
echo "<div class='btn-group'>";
|
||||
echo html::submitButton($lang->search->common, '', 'btn-primary');
|
||||
echo html::submitButton($lang->search->common);
|
||||
if($style != 'simple')
|
||||
{
|
||||
echo html::commonButton($lang->search->reset, 'onclick=resetForm(this) class=btn');
|
||||
echo html::commonButton($lang->save, 'onclick=saveQuery() class=btn');
|
||||
echo html::commonButton($lang->search->reset, 'onclick=resetForm(this)');
|
||||
echo html::commonButton($lang->save, 'onclick=saveQuery()');
|
||||
}
|
||||
echo '</div>';
|
||||
?>
|
||||
@@ -413,10 +414,8 @@ foreach($fieldParams as $fieldName => $param)
|
||||
<?php if($style != 'simple'):?>
|
||||
<td class='w-120px'>
|
||||
<div class='input-group'>
|
||||
<?php
|
||||
echo html::select('queryID', $queries, $queryID, 'onchange=executeQuery(this.value) class=form-control');
|
||||
if(common::hasPriv('search', 'deleteQuery')) echo "<span class='input-group-btn'>" . html::a('javascript:deleteQuery()', '<i class="icon-remove"></i>', '', 'class=btn') . '</span>';
|
||||
?>
|
||||
<span id='queryBox'><?php echo html::select('queryID', $queries, $queryID, 'onchange=executeQuery(this.value) class=form-control');?></span>
|
||||
<?php if(common::hasPriv('search', 'deleteQuery')) echo "<span class='input-group-btn'>" . html::a('javascript:deleteQuery()', '<i class="icon-remove"></i>', '', 'class=btn') . '</span>';?>
|
||||
</div>
|
||||
</td>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -17,7 +17,6 @@ $config->story->change = new stdclass();
|
||||
$config->story->close = new stdclass();
|
||||
$config->story->review = new stdclass();
|
||||
$config->story->create->requiredFields = 'title';
|
||||
$config->story->edit->requiredFields = 'title';
|
||||
$config->story->change->requiredFields = 'title';
|
||||
$config->story->close->requiredFields = 'closedReason';
|
||||
$config->story->review->requiredFields = 'assignedTo,reviewedBy,result';
|
||||
|
||||
@@ -1054,7 +1054,8 @@ class story extends control
|
||||
$productName = $this->product->getById($story->product)->name;
|
||||
|
||||
/* Get actions. */
|
||||
$action = $this->action->getById($actionID);
|
||||
$actions = $this->action->getList('story', $storyID);
|
||||
$action = zget($actions, $actionID, null);
|
||||
$history = $this->action->getHistory($actionID);
|
||||
$action->history = isset($history[$actionID]) ? $history[$actionID] : array();
|
||||
if(strtolower($action->action) == 'opened') $action->comment = $story->spec;
|
||||
|
||||
@@ -2,4 +2,5 @@ $(document).ready(function()
|
||||
{
|
||||
$('#zerocaseTab').addClass('active');
|
||||
fixedTfootAction('#productStoryForm');
|
||||
fixedTheadOfList('#storyList');
|
||||
});
|
||||
|
||||
@@ -433,7 +433,6 @@ class storyModel extends model
|
||||
$this->dao->update(TABLE_STORY)
|
||||
->data($story)
|
||||
->autoCheck()
|
||||
->batchCheck($this->config->story->edit->requiredFields, 'notempty')
|
||||
->checkIF(isset($story->closedBy), 'closedReason', 'notempty')
|
||||
->checkIF(isset($story->closedReason) and $story->closedReason == 'done', 'stage', 'notempty')
|
||||
->checkIF(isset($story->closedReason) and $story->closedReason == 'duplicate', 'duplicateStory', 'notempty')
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<td></td>
|
||||
<td colspan='2'>
|
||||
<?php
|
||||
echo html::submitButton(html::icon($lang->icons['activate']) . ' ' . $lang->story->activate, '', 'btn-success');
|
||||
echo html::submitButton(html::icon($lang->icons['activate']) . ' ' . $lang->story->activate, '', 'btn btn-success');
|
||||
echo html::linkButton($lang->goback, $app->session->storyList ? $app->session->storyList : inlink('view', "storyID=$story->id"));
|
||||
?>
|
||||
</td>
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
<td></td><td class='text-center'>
|
||||
<?php
|
||||
echo html::hidden('lastEditedDate', $story->lastEditedDate);
|
||||
echo html::submitButton('', '', 'btn-primary');
|
||||
echo html::submitButton();
|
||||
echo html::linkButton($lang->goback, $app->session->storyList ? $app->session->storyList : inlink('view', "storyID=$story->id"));
|
||||
?>
|
||||
</td>
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
<div class='panel-body' style='padding-top:0'>
|
||||
<form method='post'>
|
||||
<?php echo html::checkBox('charts', $lang->story->report->charts, $checkedCharts, '', 'block');?>
|
||||
<?php echo html::selectAll('', "button", false, 'btn-sm')?>
|
||||
<?php echo html::submitButton($lang->story->report->create, '', 'btn-sm btn-primary');?>
|
||||
<?php echo html::selectAll('', "button", false, 'btn btn-sm')?>
|
||||
<?php echo html::submitButton($lang->story->report->create, '', 'btn btn-sm btn-primary');?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -275,12 +275,23 @@
|
||||
</div>
|
||||
<div class='tab-pane' id='legendRelated'>
|
||||
<table class='table table-data table-condensed table-borderless'>
|
||||
<tr class='text-top'>
|
||||
<th class='w-70px'><?php echo $lang->story->legendFromBug;?></th>
|
||||
<td class='pd-0'>
|
||||
<ul class='list-unstyled'>
|
||||
<?php if(!empty($fromBug)) echo "<li title='#$fromBug->id $fromBug->title'>" . html::a($this->createLink('bug', 'view', "bugID=$fromBug->id"), "#$fromBug->id $fromBug->title") . '</li>';?>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='text-top'>
|
||||
<th class='w-70px'><?php echo $lang->story->legendBugs;?></th>
|
||||
<td class='pd-0'>
|
||||
<ul class='list-unstyled'>
|
||||
<?php
|
||||
if(!empty($fromBug)) echo "<li title='#$fromBug->id $fromBug->title'>" . html::a($this->createLink('bug', 'view', "bugID=$fromBug->id"), "#$fromBug->id $fromBug->title") . " <span class='label label-warning'>{$lang->story->legendFromBug}</span></li>";
|
||||
foreach($bugs as $bug)
|
||||
{
|
||||
echo "<li title='#$bug->id $bug->title'>" . html::a($this->createLink('bug', 'view', "bugID=$bug->id"), "#$bug->id $bug->title") . '</li>';
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</td>
|
||||
@@ -308,10 +319,19 @@
|
||||
{
|
||||
if(isset($story->extraStories[$linkStoryID])) echo '<li>' . html::a(inlink('view', "storyID=$linkStoryID"), "#$linkStoryID " . $story->extraStories[$linkStoryID]) . '</li>';
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='text-top'>
|
||||
<th><?php echo $lang->story->legendChildStories;?></th>
|
||||
<td class='pd-0'>
|
||||
<ul class='list-unstyled'>
|
||||
<?php
|
||||
$childStories = explode(',', $story->childStories) ;
|
||||
foreach($childStories as $childStoryID)
|
||||
{
|
||||
if(isset($story->extraStories[$childStoryID])) echo '<li>' . html::a(inlink('view', "storyID=$childStoryID"), "#$childStoryID " . $story->extraStories[$childStoryID]) . " <span class='label label-info'>{$lang->story->legendChildStories}</span></li>";
|
||||
if(isset($story->extraStories[$childStoryID])) echo '<li>' . html::a(inlink('view', "storyID=$childStoryID"), "#$childStoryID " . $story->extraStories[$childStoryID]) . '</li>';
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
<td colspan='11'>
|
||||
<div class='table-actions clearfix'>
|
||||
<?php if(count($stories)):?>
|
||||
<div class='btn-group'><?php echo html::selectButton();?></div>
|
||||
<?php echo html::selectButton();?>
|
||||
<?php
|
||||
$canBatchEdit = common::hasPriv('story', 'batchEdit');
|
||||
$disabled = $canBatchEdit ? '' : "disabled='disabled'";
|
||||
|
||||
@@ -61,7 +61,7 @@ function setPreview()
|
||||
else
|
||||
{
|
||||
storyLink = createLink('story', 'view', "storyID=" + $('#story').val());
|
||||
var concat = config.requestType == 'PATH_INFO' ? '?' : '&';
|
||||
var concat = config.requestType != 'GET' ? '?' : '&';
|
||||
storyLink = storyLink + concat + 'onlybody=yes';
|
||||
$('#preview').removeClass('hidden');
|
||||
$('#preview a').attr('href', storyLink);
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<form method='post'>
|
||||
<?php echo html::checkBox('charts', $lang->task->report->charts, $checkedCharts, '', 'block')?>
|
||||
<?php echo html::selectAll('', "button", false, 'btn-sm')?>
|
||||
<?php echo html::submitButton($lang->task->report->create, "", 'btn-sm btn-primary');?>
|
||||
<?php echo html::submitButton($lang->task->report->create, "", 'btn btn-sm btn-primary');?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -56,10 +56,10 @@ class testcase extends control
|
||||
{
|
||||
/* Set browseType, productID, moduleID and queryID. */
|
||||
$browseType = strtolower($browseType);
|
||||
$productID = $this->product->saveState($productID, $this->products);
|
||||
if($branch === '') $branch = $this->session->branch;
|
||||
$moduleID = ($browseType == 'bymodule') ? (int)$param : 0;
|
||||
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
|
||||
$productID = $this->product->saveState($productID, $this->products);
|
||||
$branch = ($branch === '') ? $this->session->branch : $branch;
|
||||
$moduleID = ($browseType == 'bymodule') ? (int)$param : 0;
|
||||
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
|
||||
|
||||
/* Set menu, save session. */
|
||||
$this->testcase->setMenu($this->products, $productID, $branch);
|
||||
@@ -77,62 +77,8 @@ class testcase extends control
|
||||
$pager = pager::init($recTotal, $recPerPage, $pageID);
|
||||
$sort = $this->loadModel('common')->appendOrder($orderBy);
|
||||
|
||||
/* By module or all cases. */
|
||||
if($browseType == 'bymodule' or $browseType == 'all')
|
||||
{
|
||||
$childModuleIds = $this->tree->getAllChildId($moduleID);
|
||||
$cases = $this->testcase->getModuleCases($productID, $branch, $childModuleIds, $sort, $pager);
|
||||
}
|
||||
/* Cases need confirmed. */
|
||||
elseif($browseType == 'needconfirm')
|
||||
{
|
||||
$cases = $this->dao->select('t1.*, t2.title AS storyTitle')->from(TABLE_CASE)->alias('t1')->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
|
||||
->where("t2.status = 'active'")
|
||||
->andWhere('t1.deleted')->eq(0)
|
||||
->andWhere('t2.version > t1.storyVersion')
|
||||
->orderBy($sort)
|
||||
->page($pager)
|
||||
->fetchAll();
|
||||
}
|
||||
/* By search. */
|
||||
elseif($browseType == 'bysearch')
|
||||
{
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('testcaseQuery', $query->sql);
|
||||
$this->session->set('testcaseForm', $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set('testcaseQuery', ' 1 = 1');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->testcaseQuery == false) $this->session->set('testcaseQuery', ' 1 = 1');
|
||||
}
|
||||
|
||||
$queryProductID = $productID;
|
||||
$allProduct = "`product` = 'all'";
|
||||
|
||||
$caseQuery = '(' . $this->session->testcaseQuery;
|
||||
if(strpos($this->session->testcaseQuery, $allProduct) !== false)
|
||||
{
|
||||
$products = array_keys($this->loadModel('product')->getPrivProducts());
|
||||
$caseQuery = str_replace($allProduct, '1', $caseQuery);
|
||||
$caseQuery = $caseQuery . ' AND `product`' . helper::dbIN($products);
|
||||
$queryProductID = 'all';
|
||||
}
|
||||
$caseQuery .= ')';
|
||||
|
||||
$cases = $this->dao->select('*')->from(TABLE_CASE)->where($caseQuery)
|
||||
->beginIF($queryProductID != 'all')->andWhere('product')->eq($productID)->fi()
|
||||
->andWhere('deleted')->eq(0)
|
||||
->orderBy($sort)->page($pager)->fetchAll();
|
||||
}
|
||||
/* Get test cases. */
|
||||
$cases = $this->testcase->getTestCases($productID, $branch, $browseType, $queryID, $moduleID, $sort, $pager);
|
||||
|
||||
/* save session .*/
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', $browseType != 'bysearch' ? false : true);
|
||||
@@ -141,38 +87,26 @@ class testcase extends control
|
||||
$cases = $this->loadModel('story')->checkNeedConfirm($cases);
|
||||
|
||||
/* Build the search form. */
|
||||
$this->config->testcase->search['params']['product']['values']= array($productID => $this->products[$productID], 'all' => $this->lang->testcase->allProduct);
|
||||
$this->config->testcase->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($productID, $viewType = 'case');
|
||||
if($this->session->currentProductType == 'normal')
|
||||
{
|
||||
unset($this->config->testcase->search['fields']['branch']);
|
||||
unset($this->config->testcase->search['params']['branch']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->config->testcase->search['fields']['branch'] = $this->lang->product->branch;
|
||||
$this->config->testcase->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty');
|
||||
}
|
||||
$this->config->testcase->search['actionURL'] = $this->createLink('testcase', 'browse', "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID");
|
||||
$this->config->testcase->search['queryID'] = $queryID;
|
||||
$actionURL = $this->createLink('testcase', 'browse', "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID");
|
||||
$this->testcase->buildSearchForm($productID, $this->products, $queryID, $actionURL);
|
||||
$this->loadModel('search')->setSearchParams($this->config->testcase->search);
|
||||
|
||||
/* Assign. */
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testcase->common;
|
||||
$this->view->position[] = html::a($this->createLink('testcase', 'browse', "productID=$productID&branch=$branch"), $this->products[$productID]);
|
||||
$this->view->position[] = $this->lang->testcase->common;
|
||||
$this->view->productID = $productID;
|
||||
$this->view->productName = $this->products[$productID];
|
||||
$this->view->moduleTree = $this->tree->getTreeMenu($productID, $viewType = 'case', $startModuleID = 0, array('treeModel', 'createCaseLink'), '', $branch);
|
||||
$this->view->moduleID = $moduleID;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->users = $this->user->getPairs('noletter');
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->param = $param;
|
||||
$this->view->cases = $cases;
|
||||
$this->view->branch = $branch;
|
||||
$this->view->branches = $this->loadModel('branch')->getPairs($productID);
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testcase->common;
|
||||
$this->view->position[] = html::a($this->createLink('testcase', 'browse', "productID=$productID&branch=$branch"), $this->products[$productID]);
|
||||
$this->view->position[] = $this->lang->testcase->common;
|
||||
$this->view->productID = $productID;
|
||||
$this->view->productName = $this->products[$productID];
|
||||
$this->view->moduleTree = $this->tree->getTreeMenu($productID, $viewType = 'case', $startModuleID = 0, array('treeModel', 'createCaseLink'), '', $branch);
|
||||
$this->view->moduleID = $moduleID;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->users = $this->user->getPairs('noletter');
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->param = $param;
|
||||
$this->view->cases = $cases;
|
||||
$this->view->branch = $branch;
|
||||
$this->view->branches = $this->loadModel('branch')->getPairs($productID);
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ $(document).ready(function()
|
||||
$('#module' + moduleID).addClass('active');
|
||||
if(browseType == 'bysearch') ajaxGetSearchForm();
|
||||
setTimeout(function(){fixedTfootAction('#batchForm')}, 100);
|
||||
setTimeout(function(){fixedTheadOfList('#caseList')}, 100);
|
||||
|
||||
setModal4List('runCase', 'caseList');
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ function setPreview()
|
||||
else
|
||||
{
|
||||
storyLink = createLink('story', 'view', "storyID=" + $('#story').val());
|
||||
var concat = config.requestType == 'PATH_INFO' ? '?' : '&';
|
||||
var concat = config.requestType != 'GET' ? '?' : '&';
|
||||
storyLink = storyLink + concat + 'onlybody=yes';
|
||||
$('#preview').removeClass('hidden');
|
||||
$('#preview').attr('href', storyLink);
|
||||
|
||||
@@ -216,6 +216,81 @@ class testcaseModel extends model
|
||||
return $case;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get test cases.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $branch
|
||||
* @param string $browseType
|
||||
* @param int $queryID
|
||||
* @param int $moduleID
|
||||
* @param int $sort
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getTestCases($productID, $branch, $browseType, $queryID, $moduleID, $sort, $pager)
|
||||
{
|
||||
/* By module or all cases. */
|
||||
if($browseType == 'bymodule' or $browseType == 'all')
|
||||
{
|
||||
$cases = $this->getModuleCases($productID, $branch, $this->loadModel('tree')->getAllChildId($moduleID), $sort, $pager);
|
||||
}
|
||||
/* Cases need confirmed. */
|
||||
elseif($browseType == 'needconfirm')
|
||||
{
|
||||
$cases = $this->dao->select('t1.*, t2.title AS storyTitle')->from(TABLE_CASE)->alias('t1')->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
|
||||
->where("t2.status = 'active'")
|
||||
->andWhere('t1.deleted')->eq(0)
|
||||
->andWhere('t2.version > t1.storyVersion')
|
||||
->orderBy($sort)
|
||||
->page($pager)
|
||||
->fetchAll();
|
||||
}
|
||||
/* By search. */
|
||||
elseif($browseType == 'bysearch')
|
||||
{
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('testcaseQuery', $query->sql);
|
||||
$this->session->set('testcaseForm', $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set('testcaseQuery', ' 1 = 1');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->testcaseQuery == false) $this->session->set('testcaseQuery', ' 1 = 1');
|
||||
}
|
||||
|
||||
$queryProductID = $productID;
|
||||
$allProduct = "`product` = 'all'";
|
||||
$caseQuery = '(' . $this->session->testcaseQuery;
|
||||
if(strpos($this->session->testcaseQuery, $allProduct) !== false)
|
||||
{
|
||||
$products = array_keys($this->loadModel('product')->getPrivProducts());
|
||||
$caseQuery = str_replace($allProduct, '1', $caseQuery);
|
||||
$caseQuery = $caseQuery . ' AND `product`' . helper::dbIN($products);
|
||||
$queryProductID = 'all';
|
||||
}
|
||||
$caseQuery .= ')';
|
||||
|
||||
$cases = $this->dao->select('*')->from(TABLE_CASE)->where($caseQuery)
|
||||
->beginIF($queryProductID != 'all')->andWhere('product')->eq($productID)->fi()
|
||||
->andWhere('deleted')->eq(0)
|
||||
->orderBy($sort)->page($pager)->fetchAll();
|
||||
}
|
||||
|
||||
if($cases) return $cases;
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cases by assigento.
|
||||
*
|
||||
@@ -651,4 +726,32 @@ class testcaseModel extends model
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build search form.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param array $products
|
||||
* @param int $queryID
|
||||
* @param string $actionURL
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function buildSearchForm($productID, $products, $queryID, $actionURL)
|
||||
{
|
||||
$this->config->testcase->search['params']['product']['values'] = array($productID => $products[$productID], 'all' => $this->lang->testcase->allProduct);
|
||||
$this->config->testcase->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($productID, $viewType = 'case');
|
||||
if($this->session->currentProductType == 'normal')
|
||||
{
|
||||
unset($this->config->testcase->search['fields']['branch']);
|
||||
unset($this->config->testcase->search['params']['branch']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->config->testcase->search['fields']['branch'] = $this->lang->product->branch;
|
||||
$this->config->testcase->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty');
|
||||
}
|
||||
$this->config->testcase->search['actionURL'] = $actionURL;
|
||||
$this->config->testcase->search['queryID'] = $queryID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,9 +104,7 @@ js::set('batchDelete', $lang->testcase->confirmBatchDelete);
|
||||
<td colspan='<?php echo $mergeColums?>'>
|
||||
<?php if($cases):?>
|
||||
<div class='table-actions clearfix'>
|
||||
<div class='btn-group'>
|
||||
<?php echo html::selectButton();?>
|
||||
</div>
|
||||
<?php echo html::selectButton();?>
|
||||
<div class='btn-group dropup'>
|
||||
<?php
|
||||
$actionLink = $this->createLink('testcase', 'batchEdit', "productID=$productID&branch=$branch");
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<tr>
|
||||
<td colspan='5'>
|
||||
<?php
|
||||
echo "<div class='btn-group'>" . html::selectButton() . '</div>';
|
||||
echo html::selectButton();
|
||||
echo html::submitButton();
|
||||
?>
|
||||
</td>
|
||||
|
||||
@@ -44,14 +44,14 @@
|
||||
$task->build == 'trunk' ? print('Trunk') : print(html::a($this->createLink('build', 'view', "buildID=$task->build"), $task->buildName));;
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo $users[$task->owner];?></td>
|
||||
<td><?php echo zget($users, $task->owner);?></td>
|
||||
<td><?php echo $task->begin?></td>
|
||||
<td><?php echo $task->end?></td>
|
||||
<td class='status-<?php echo $task->status?>'><?php echo $lang->testtask->statusList[$task->status];?></td>
|
||||
<td class='text-center'>
|
||||
<?php
|
||||
common::printIcon('testtask', 'cases', "taskID=$task->id", 'play', 'list', 'smile');
|
||||
common::printIcon('testtask', 'view', "taskID=$task->id", '', 'list', 'file');
|
||||
common::printIcon('testtask', 'view', "taskID=$task->id", '', 'list', 'file');
|
||||
common::printIcon('testtask', 'linkCase', "taskID=$task->id", '', 'list', 'link');
|
||||
common::printIcon('testtask', 'edit', "taskID=$task->id", '', 'list');
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ var moduleID = '<?php echo $moduleID;?>';
|
||||
<div class='table-actions clearfix'>
|
||||
|
||||
<?php
|
||||
if($canBatchEdit or $canBatchAssign or $canBatchRun) echo "<div class='btn-group'>" . html::selectButton() . '</div>';
|
||||
if($canBatchEdit or $canBatchAssign or $canBatchRun) echo html::selectButton();
|
||||
if($canBatchEdit)
|
||||
{
|
||||
$actionLink = $this->createLink('testcase', 'batchEdit', "productID=$productID");
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
<tr>
|
||||
<td colspan='7'>
|
||||
<?php if($cases):?>
|
||||
<div class='table-actions clearfix'><?php echo "<div class='btn-group'>" . html::selectButton() . '</div>' . html::submitButton();?></div>
|
||||
<div class='table-actions clearfix'><?php echo html::selectButton() . html::submitButton();?></div>
|
||||
<?php endif;?>
|
||||
<div class='text-right'><?php $pager->show();?></div>
|
||||
</td>
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
if($preCase) echo html::a(inlink('runCase', "runID={$preCase['runID']}&caseID={$preCase['caseID']}&version={$preCase['version']}"), $lang->testtask->pre, '', "id='pre' class='btn'");
|
||||
if(empty($run->case->steps))
|
||||
{
|
||||
echo html::submitButton($lang->testtask->pass, "onclick=$('#result').val('pass')", 'btn-success');
|
||||
echo html::submitButton($lang->testtask->fail, "onclick=$('#result').val('fail')", 'btn-danger');
|
||||
echo html::submitButton($lang->testtask->pass, "onclick=$('#result').val('pass')", 'btn btn-success');
|
||||
echo html::submitButton($lang->testtask->fail, "onclick=$('#result').val('fail')", 'btn btn-danger');
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<div class='content'><?php echo $lang->upgrade->warnningContent;?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='modal-footer'><?php echo html::linkButton($lang->upgrade->common, inlink('checkExtension'), 'self', '', 'btn-primary');?></div>
|
||||
<div class='modal-footer'><?php echo html::linkButton($lang->upgrade->common, inlink('checkExtension'), 'self', '', 'btn btn-primary');?></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.lite.html.php';?>
|
||||
|
||||
@@ -658,6 +658,9 @@ class user extends control
|
||||
if($this->app->getViewType() == 'json') die(helper::removeUTF8Bom(json_encode(array('status' => 'failed', 'reason' => $failReason))));
|
||||
die(js::error($failReason));
|
||||
}
|
||||
|
||||
/* Check the login ip is in white list or not. */
|
||||
if(!$this->user->checkIP($this->server->remote_addr)) die(js::error($this->lang->user->ipLimited));
|
||||
|
||||
$user = $this->user->identify($account, $password);
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ $lang->user->loginFailed = "Login failed, please check your account and passwor
|
||||
$lang->user->lockWarning = "You only have %s times to try.";
|
||||
$lang->user->loginLocked = "You try the password too many times, please contact the administrator or try again after %s minutes.";
|
||||
$lang->user->weakPassword = "Your password strength is less than the system settings.";
|
||||
$lang->user->ipLimited = "Login failed, this ip is limited.";
|
||||
|
||||
$lang->user->roleList[''] = '';
|
||||
$lang->user->roleList['dev'] = 'Developer';
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user