From 14c1547ca8ff916d8cd86eca690fa66a876208f2 Mon Sep 17 00:00:00 2001 From: Haulyn Jason Date: Sat, 26 Jul 2014 11:20:41 +0800 Subject: [PATCH 1/3] change Callable to CallableInterface to fit PHP5.4 --- lib/class/helpable.php | 42 ++++++------- lib/helper/db.php | 140 ++++++++++++++++++++--------------------- 2 files changed, 91 insertions(+), 91 deletions(-) diff --git a/lib/class/helpable.php b/lib/class/helpable.php index 2a6b71c..17099f4 100644 --- a/lib/class/helpable.php +++ b/lib/class/helpable.php @@ -1,7 +1,7 @@ * @version 0.2 @@ -10,7 +10,7 @@ /** * Helpable - * + * * add possibility to have helpers, and call helper method if it doesn't exist * @since 0.1 */ @@ -21,7 +21,7 @@ abstract class Helpable { public function __construct() { $this->_helpers = array(); } - + /** * add helper to the class * @param string $helper name of helper (flat format) @@ -53,10 +53,10 @@ public function addHelper() { break; default: $this->_helpers[$helper] = new $class($obj); - break; + break; } } - + /** * call helper method * @param string $key the helper key @@ -68,7 +68,7 @@ public function callHelper() { $method = array_shift($args); return call_user_func_array(array($this->_helpers[$helper], $method), $args); } - + /** * call helper's method (arguments are passed as an array */ @@ -82,7 +82,7 @@ public function callHelperArray() { return $this->_helpers[$helper]->$method(); } } - + /** * call all available helpers method * @param string $method the method to be called @@ -103,14 +103,14 @@ protected function callHelpers($method) { } return $arr; } - + /** * check if helper is available */ public function hasHelper($helper) { return array_key_exists($helper, $this->_helpers); } - + /** * get helper */ @@ -121,7 +121,7 @@ public function &getHelper($helper) { throw new AppException('Unknown helper '.$helper.' in '.get_class($this)); } } - + /** * call helper method if not defined here */ @@ -129,7 +129,7 @@ public function __call($name, $args) { if (!count($this->_helpers)) { throw new AppException('Unknown method '.$name.' in '.get_class($this).' (and no helper available)'); } - + // check if helper's name has been added to method's name eg. methodHelper /* TOO UGLY, TOO COSTY $subname = StringHelper::camelToFlat($name); @@ -140,25 +140,25 @@ public function __call($name, $args) { $obj = $this->_helpers[$subhelp]; if (method_exists($obj, $name)) { return call_user_func_array(array($obj, $name), $args); - } + } } } */ - + // check if method exists in one of the helper foreach ($this->_helpers as $key => $obj) { if (method_exists($obj, $name)) { return call_user_func_array(array($obj, $name), $args); } } - + // try again within helper if __call is available foreach ($this->_helpers as $key => $obj) { if (method_exists($obj, '__call')) { return call_user_func_array(array($obj, $name), $args); } } - + // nope, forget it throw new AppException('Unknown method '.$name.' in '.get_class($this).' or any helper ('.implode(', ',array_keys($this->_helpers)).')'); } @@ -170,7 +170,7 @@ public function __call($name, $args) { * sucks duplicating code, but needed for singletons as constructor must be private * @since 0.1 */ - + abstract class HelpableSingleton { private $_helpers; @@ -178,7 +178,7 @@ abstract class HelpableSingleton { private function __construct() { $this->_helpers = array(); } - + /** * add helper to the class */ @@ -186,14 +186,14 @@ protected function addHelper($helper, $obj=null) { $class = StringHelper::flatToCamel($helper, true).'Helper'; $this->_helpers[$helper] = new $class($obj); } - + /** * check if helper is available */ public function hasHelper($helper) { return array_key_exists($helper, $this->_helpers); } - + /** * get helper */ @@ -204,7 +204,7 @@ public function &getHelper($helper) { throw new AppException('Unknown helper '.$helper.' in '.get_class($this)); } } - + /** * call helper method if not defined here */ @@ -231,7 +231,7 @@ public function __call($name, $args) { * * class implementing this will be able to send calls to other nested classes */ -interface Callable { +interface CallableInterface { public function __call($name, $args); /* public function __call($name, $args) { diff --git a/lib/helper/db.php b/lib/helper/db.php index f323891..42c2e15 100644 --- a/lib/helper/db.php +++ b/lib/helper/db.php @@ -1,7 +1,7 @@ * @version 0.5 @@ -11,33 +11,33 @@ /** * DbHelper - * + * * Database helper to give Models (or other classes) database capabilities */ -class DbHelper extends Helper implements Callable { +class DbHelper extends Helper implements CallableInterface { protected $db; protected $qry; - + protected $idx; protected $rows; protected $total; - + protected $table; - + public function __construct($obj, $table) { parent::__construct($obj); $this->db = DbConnector::getConnection(); $this->qry = new DbQueryHelper(); $this->table = $table; } - + public static function factory() { return new DbHelper(null, ''); } - + // ----- INSERTion queries --------------------------------------------------- - + public function save() { // check UID $uid = $this->obj->getUid(); @@ -47,7 +47,7 @@ public function save() { return $this->update(); } } - + public function insert() { // set creation date if (!$this->_creationDate()) { @@ -64,12 +64,12 @@ public function insert() { } return false; } - + public function replace() { $sql = 'REPLACE `'.$this->obj->dbTable().'` SET '.$this->fields(); return $this->db->query($sql); } - + public function update($filter='') { if (!$this->buildWhere($filter)) { return false; @@ -81,7 +81,7 @@ public function update($filter='') { $sql .= ' WHERE '.$filter; return $this->db->query($sql); } - + protected function fields() { $fields = $this->obj->getFields(); $arr = ''; @@ -94,12 +94,12 @@ protected function fields() { } return implode(', ',$arr); } - + public function sql($key) { $val = $this->obj->get($key); return $this->sqlValue($val); } - + public function sqlValue($val) { if (is_integer($val)) { return $val; @@ -109,9 +109,9 @@ public function sqlValue($val) { return "'".$this->db->escapeString($val)."'"; } } - + // ----- DELETE query ------------------------------------------------------- - + /** * delete entry * @param string $filter if not set, will delete by UID @@ -125,10 +125,10 @@ public function delete($filter='') { $sql .= ' WHERE '.$filter; return $this->db->query($sql); } - - + + // ----- LOAD queries -------------------------------------------------------- - + /** * load one item * @param mixed filter either an array (key/value), a string, or nothing if you want to load by ID @@ -155,7 +155,7 @@ public function load($filter='', $auto=true) { $this->obj->setUid(0); return false; } - + /** * load a list of items */ @@ -185,22 +185,22 @@ public function loadList($auto=true) { } return false; } - + /** * query database and return result set directly */ public function loadRaw() { return $this->db->query($this->qry->build()); } - + public function count() { return count($this->rows); } - + public function total() { return $this->total; } - + public function next() { if (array_key_exists($this->idx, $this->rows)) { if (is_a($this->obj, 'Model')) { @@ -213,11 +213,11 @@ public function next() { return false; } } - + public function reset() { $this->rows = array(); } - + /** * set limit by giving a page size and page number */ @@ -228,11 +228,11 @@ public function page($size=10, $page=1) { if (!$page) { $page = 1; } - $this->qry->limit(($page - 1) * $size, $size); + $this->qry->limit(($page - 1) * $size, $size); } - + // ---- TABLE & FIELDS MANIPULATION ------------------------------------------ - + /** * Get database table * @todo add DB table prefix @@ -243,7 +243,7 @@ public function dbTable($table='') { } return $this->qry->prefixTable($table); } - + /** * returns a SQL statement table.field = value */ @@ -254,7 +254,7 @@ public function dbField($field, $value='') { } return $str; } - + /** * */ @@ -265,16 +265,16 @@ public function dbUid($ext=false) { return $this->obj->proUid(); } } - + /** * get SQL formatted UID */ public function sqlUid() { return $this->sql($this->obj->proUid()); } - + // ---- MISC QUERIES --------------------------------------------------------- - + /** * check if value already exists in table */ @@ -288,9 +288,9 @@ public function findOccurences($key, $val) { } return 0; } - + // ---- QUERY BUILDER Methods ------------------------------------------------ - + /** * build default SELECT query * @todo might not want to reset query every time @@ -303,7 +303,7 @@ public function buildSelect() { // add SELECT clause $this->qry->select($select); } - + /** * build FROM clause */ @@ -311,7 +311,7 @@ public function buildFrom() { // add FROM clause $this->qry->from($this->dbTable()); } - + /** * build SELECT and JOIN clauses */ @@ -338,13 +338,13 @@ public function buildFields($nested='') { } return $select; } - + /** * build WHERE clause based on filter */ public function buildWhere(&$filter) { if (is_array($filter)) { - // filter + // filter $filter = '`'.$filter[0]."`='".$filter[1]."'"; } else if (preg_match('/^[a-zA-Z0-9\_]+$/',$filter)) { // filter on a field already set in DB @@ -352,7 +352,7 @@ public function buildWhere(&$filter) { } else if (empty($filter)) { // nothing set, try on ID if ($id = $this->obj->getUid()) { - $filter = $this->obj->dbUid($this->qry->doesJoin())."=".$this->obj->sqlUid(); + $filter = $this->obj->dbUid($this->qry->doesJoin())."=".$this->obj->sqlUid(); } else { // not filter and no ID provided, don't even try $filter = ''; @@ -362,9 +362,9 @@ public function buildWhere(&$filter) { // overwise, consider param as a ready set where statement return true; } - + // ---- MISCELLANEOUS -------------------------------------------------------- - + protected function _creationDate() { $fields = $this->obj->getFields(); if (array_key_exists('creation_date', $fields)) { @@ -373,7 +373,7 @@ protected function _creationDate() { } return false; } - + protected function _lastChangeDate() { $fields = $this->obj->getFields(); if (array_key_exists('last_change_date', $fields)) { @@ -382,7 +382,7 @@ protected function _lastChangeDate() { } return false; } - + public function __call($name, $args) { $arr = array('db','qry'); foreach ($arr as $class) { @@ -392,7 +392,7 @@ public function __call($name, $args) { } throw new AppException('Unknown method '.$name.' in '.__CLASS__.', '.implode(', ',$arr)); } - + } /** @@ -401,9 +401,9 @@ public function __call($name, $args) { * SQL SELECT Query Builder */ class DbQueryHelper { - + protected $sql; - + public function __construct() { $this->sql = array( 'select' => '', @@ -416,7 +416,7 @@ public function __construct() { 'limit' => '' ); } - + /** * reset all or part of the SQL query */ @@ -429,9 +429,9 @@ public function reset($part='') { } $this->sql['join'] = array(); } - + } - + /** * add fields in SELECT */ @@ -445,7 +445,7 @@ public function select($field) { $this->sql['select'] = (($this->sql['select'])?($this->sql['select'].','):'').implode(',', $field); } } - + /** * add FROM statement */ @@ -456,7 +456,7 @@ public function from($table) { $this->sql['from'] = '`'.$this->prefixTable($table).'`'; } } - + /** * add any JOIN */ @@ -475,49 +475,49 @@ public function join($table, $on, $how = '') { } $this->sql['join'][] = $str; } - + /** * add INNER JOIN */ public function innerJoin($table, $on) { $this->join($table, $on, 'INNER'); } - + /** * add LEFT JOIN */ public function leftJoin($table, $on) { $this->join($table, $on, 'LEFT'); } - + /** * add WHERE condition */ public function where($filter, $sep='AND') { $this->sql['where'] = $this->concatSQL($this->sql['where'], $filter, $sep); } - + /** * add GROUP BY condition */ public function groupBy($filter, $sep=',') { $this->sql['groupBy'] = $this->concatSQL($this->sql['groupBy'], $filter, $sep); } - + /** * add ORDER BY statement */ public function orderBy($filter, $sep=',') { $this->sql['orderBy'] = $this->concatSQL($this->sql['orderBy'], $filter, $sep); } - + /** * add HAVING condition */ public function having($filter, $sep='AND') { $this->sql['having'] = $this->concatSQL($this->sql['having'], $filter, $sep); } - + /** * add a LIMIT statement (only one statement allowed) */ @@ -527,9 +527,9 @@ public function limit($start=0, $length=1) { } $this->sql['limit'] = $start.', '.$length; } - + /** - * Query builder routine + * Query builder routine * @param boolean $total will query for total number of rows when set to true */ public function build($total=false) { @@ -570,9 +570,9 @@ public function build($total=false) { } return $sql; } - + // --- MISCELLANEOUS --------------------------------------------------------- - + /** * add prefix to table name */ @@ -587,21 +587,21 @@ public function prefixTable($table) { return $table; } } - + /** * check if joigning multi tables */ public function doesJoin() { return empty($this->sql['join'])?false:true; } - + /** * check if limit has been set */ public function doesLimit() { return empty($this->sql['limit'])?false:true; } - + /** * concat string for SQL */ @@ -622,7 +622,7 @@ protected function concatSQL($begin, $end, $separator = 'AND', $instruction = '' return $begin.$separator.$end; } } - + /** * build condition to include in a WHERE clause * @param string param the value searched. Can contain wildcards. @@ -645,5 +645,5 @@ public static function parseSearch($param) { $db = DbConnector::getConnection(); return $db->escapeString($param); } - + } \ No newline at end of file From 979efa96c968f51d65c5e13785530f3714a073ac Mon Sep 17 00:00:00 2001 From: Haulyn Jason Date: Sat, 26 Jul 2014 11:43:28 +0800 Subject: [PATCH 2/3] add ID to task list --- app/config/db.php | 6 ++--- app/view/include/list-compact.php | 8 ++++--- app/view/include/list-expand.php | 39 ++++++++++++++++--------------- skin/default/css/list.css | 10 ++++---- 4 files changed, 33 insertions(+), 30 deletions(-) diff --git a/app/config/db.php b/app/config/db.php index 6aa7ee3..e1f1419 100644 --- a/app/config/db.php +++ b/app/config/db.php @@ -1,9 +1,9 @@   + ID order == 'deadline') echo ' class="active"'; ?>> order == 'priority') echo ' class="active"'; ?>> - data->total(); echo $ct.' '.TR::html('data',($ct>1)?'items_found':'item_found'); ?> @@ -51,6 +52,7 @@ } $total += $this->data->get('spent'); ?> + data->getUid();?> data->htmlDeadline(); ?> fc->getUrl('task','timer',array('id'=>$id)).'" ' .'class="onhold clock ajax" title="'.TR::html('ui','start_task').'" rel="drun">'.TR::html('button','start').''; } - + echo ''; if (!$this->expand && $cid == $id) { echo TR::html('task','running'); @@ -99,7 +101,7 @@ - + | actions as $key => $label) { diff --git a/app/view/include/list-expand.php b/app/view/include/list-expand.php index b3f86cd..c710611 100644 --- a/app/view/include/list-expand.php +++ b/app/view/include/list-expand.php @@ -16,19 +16,20 @@ // start list echo HtmlFormHelper::iForm('tasks'); - + ?> + order == 'deadline') echo ' class="active"'; ?>> order == 'priority') echo ' class="active"'; ?>> - 1)?'items_found':'item_found'); ?> @@ -49,9 +50,9 @@ current)?$this->current->getUid():0; - + for($j=0;$j<=$c;$j++) { $arrObj = $arrData[$j]; $d = count($arrObj); @@ -59,29 +60,29 @@ $str = ''; $subtotal = 0; $obj = $arrObj[0]; - + $id = $obj->getUid(); - + // first loop to get total time spent on task foreach ($arrObj as $obj) { $subtotal += $obj->get('spent'); } $total += $subtotal; - + $obj->chkDeadline(); - + // first row displays task information echo 'filter)?$obj->curCss(($d>1)?'noline':''):($d>1?' class="noline"':'')) .'>'; - + // checkbox echo ''; - + echo ''; // deadline echo ''; - + echo ''; - + echo ''; - + if ($d == 1) { // no timers defined, skip to next task continue; } - + // second loop to display timers foreach ($arrObj as $obj) { $id = $obj->getUid(); @@ -136,7 +137,7 @@ echo ''; - + // checkbox echo ''; // deadline @@ -149,7 +150,7 @@ echo ''; // time spent echo ''; - + echo ''; } } @@ -157,7 +158,7 @@ -
 ID
'.$obj->getUid().''.$obj->htmlDeadline().''; // edit link echo ''; if ($obj->isOpened($this->user_id)) { @@ -121,14 +122,14 @@ } echo TaskSummary::htmlTime($subtotal); echo '
 '.$obj->htmlEnd().''.$obj->getTimeSpent().'
+ | actions as $key => $label) { diff --git a/skin/default/css/list.css b/skin/default/css/list.css index 472a8f2..3864583 100644 --- a/skin/default/css/list.css +++ b/skin/default/css/list.css @@ -132,20 +132,20 @@ ul.links li.active a, p.links a.active { #dlist.tasks table thead th:first-child, #dlist.tasks table tbody td:first-child { width: 2%; } -#dlist.tasks table thead th:nth-child(2), #dlist.tasks table tbody td:nth-child(2) { +#dlist.tasks table thead th:nth-child(3), #dlist.tasks table tbody td:nth-child(3) { text-align: left; width: 9%; } -#dlist.tasks table thead th:nth-child(3), #dlist.tasks table tbody td:nth-child(3) { +#dlist.tasks table thead th:nth-child(4), #dlist.tasks table tbody td:nth-child(4) { text-align: left; width: 62%; } -#dlist.tasks table thead th:nth-child(4), #dlist.tasks table tbody td:nth-child(4), -#dlist.tasks table thead th:nth-child(5), #dlist.tasks table tbody td:nth-child(5) { +#dlist.tasks table thead th:nth-child(5), #dlist.tasks table tbody td:nth-child(5), +#dlist.tasks table thead th:nth-child(6), #dlist.tasks table tbody td:nth-child(6) { text-align: center; width: 9%; } -#dlist.tasks table thead th:nth-child(6), #dlist.tasks table tbody td:nth-child(6) { +#dlist.tasks table thead th:nth-child(7), #dlist.tasks table tbody td:nth-child(7) { text-align: right; width: 9%; } From 92b309b4667bc41eed93cbc253b99b5b9112ffe7 Mon Sep 17 00:00:00 2001 From: Haulyn Jason Date: Sat, 26 Jul 2014 11:49:41 +0800 Subject: [PATCH 3/3] add README --- README | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README b/README index c6d883a..95b1c1f 100644 --- a/README +++ b/README @@ -5,4 +5,12 @@ released : 2010-06-11 status : beta ------------------------ -Open DOCS/ folder for licence and setup info \ No newline at end of file +Open DOCS/ folder for licence and setup info + +这是一个用于追踪工作时间的小应用,分为单用户模式和多用户模式.其中,单用户模式只能一个人登录后添加任务,追踪时间,多用户模式可以设置多个用户,其中有三种角色:管理员,任务管理员和普通用户.管理员可以设置任何人的任务,同时可以管理用户;任务管理员可以查看/编辑/创建别人的任务,普通用户只能查看/设置/编辑自己的任务. + +任何人都可以在任务中设置:开始,暂停,结束.系统会自动统计出每一项任务花费的时间以及花费的总时间. + +这个程序由TaskFreak创始人编写,原名叫Time Tracking,因为不兼容PHP5.4,我做了一点小修改,使其能够在PHP5.4下面正常运行. + +在此对 http://www.taskfreak.com 表示感谢. \ No newline at end of file