From b4912256781dcc0797dbe7f12bd9dec6718641db Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 1 Apr 2016 16:56:58 +0000 Subject: [PATCH] Extended the Locking plugin with cron specification fo locks. --- WEB-INF/lib/ttTeamHelper.class.php | 5 ++++- WEB-INF/lib/ttUser.class.php | 21 +++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/locking.tpl | 4 ++-- dbinstall.php | 1 + locking.php | 23 +++++++++++++---------- mysql.sql | 2 ++ 7 files changed, 42 insertions(+), 16 deletions(-) diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 1cf71d86..8cc9660b 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -723,6 +723,7 @@ class ttTeamHelper { $tracking_mode_part = ''; $record_type_part = ''; $plugins_part = ''; + $lock_spec_part = ''; if (isset($fields['address'])) $addr_part = ', address = '.$mdb2->quote($fields['address']); if (isset($fields['currency'])) $currency_part = ', currency = '.$mdb2->quote($fields['currency']); @@ -735,9 +736,11 @@ class ttTeamHelper { if (isset($fields['tracking_mode'])) $tracking_mode_part = ', tracking_mode = '.intval($fields['tracking_mode']); if (isset($fields['record_type'])) $record_type_part = ', record_type = '.intval($fields['record_type']); if (isset($fields['plugins'])) $plugins_part = ', plugins = '.$mdb2->quote($fields['plugins']); + if (isset($fields['lock_spec'])) $lock_spec_part = ', lock_spec = '.$mdb2->quote($fields['lock_spec']); $sql = "update tt_teams set $name_part $addr_part $currency_part $locktime_part $lang_part $decimal_mark_part - $date_format_part $time_format_part $week_start_part $tracking_mode_part $record_type_part $plugins_part where id = $team_id"; + $date_format_part $time_format_part $week_start_part $tracking_mode_part $record_type_part + $plugins_part $lock_spec_part where id = $team_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) { diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index a14f7cdd..a6731a4e 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -49,6 +49,7 @@ class ttUser { var $custom_logo = 0; // Whether to use a custom logo for team. var $address = null; // Address for invoices. var $lock_interval = 0; // Lock interval in days for time records. + var $lock_spec = null; // Cron specification for record locking. var $rights = 0; // A mask of user rights. // Constructor. @@ -61,7 +62,8 @@ class ttUser { $mdb2 = getConnection(); $sql = "SELECT u.id, u.login, u.name, u.team_id, u.role, u.client_id, u.email, t.name as team_name, - t.address, t.currency, t.locktime, t.lang, t.decimal_mark, t.date_format, t.time_format, t.week_start, t.tracking_mode, t.record_type, t.plugins, t.custom_logo + t.address, t.currency, t.locktime, t.lang, t.decimal_mark, t.date_format, t.time_format, t.week_start, + t.tracking_mode, t.record_type, t.plugins, t.lock_spec, t.custom_logo FROM tt_users u LEFT JOIN tt_teams t ON (u.team_id = t.id) WHERE "; if ($id) $sql .= "u.id = $id"; @@ -94,6 +96,7 @@ class ttUser { $this->address = $val['address']; $this->currency = $val['currency']; $this->plugins = $val['plugins']; + $this->lock_spec = $val['lock_spec']; $this->custom_logo = $val['custom_logo']; $this->lock_interval = $val['locktime']; @@ -176,7 +179,9 @@ class ttUser { // isDateLocked checks whether a specifc date is locked for modifications. function isDateLocked($date) { - if ($this->isPluginEnabled('lk')) { + if ($this->isPluginEnabled('lk') && $this->lock_spec) { + // This is legacy code... + /* // Determine lock date. Entries earlier than lock date cannot be created or modified. $lockdate = 0; if ($this->lock_interval > 0) { @@ -185,6 +190,18 @@ class ttUser { } if($lockdate && $date->before($lockdate)) return true; + */ + + // New code with cron specification. + require_once(LIBRARY_DIR.'/tdcron/class.tdcron.php'); + require_once(LIBRARY_DIR.'/tdcron/class.tdcron.entry.php'); + + // Calculate the last occurrence of a lock. + $last = tdCron::getLastOccurrence($this->lock_spec, mktime()); + $lockdate = new DateAndTime(DB_DATEFORMAT, strftime('%Y-%m-%d', $last)); + if ($date->before($lockdate)) { + return true; + } } return false; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d18884c2..ab87a978 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.9.21.3467 | Copyright © Anuko | +  Anuko Time Tracker 1.9.22.3468 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/locking.tpl b/WEB-INF/templates/locking.tpl index 94e706a3..177f5918 100644 --- a/WEB-INF/templates/locking.tpl +++ b/WEB-INF/templates/locking.tpl @@ -4,8 +4,8 @@ - - + + diff --git a/dbinstall.php b/dbinstall.php index b6ddb1eb..1429a24f 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -516,6 +516,7 @@ if ($_POST) { setChange("ALTER TABLE tt_invoices ADD COLUMN status tinyint(4) default '1'"); setChange("DROP INDEX name_idx on tt_invoices"); setChange("create unique index name_idx on tt_invoices(team_id, name, status)"); + setChange("ALTER TABLE tt_teams ADD COLUMN lock_spec varchar(255) default NULL"); } // The update_clients function updates projects field in tt_clients table. diff --git a/locking.php b/locking.php index 09a7cf95..2383178f 100644 --- a/locking.php +++ b/locking.php @@ -36,22 +36,25 @@ if (!ttAccessCheck(right_manage_team)) { exit(); } -$cl_lock_interval = $request->isPost() ? $request->getParameter('lock_interval') : $user->lock_interval; +$cl_lock_spec = $request->isPost() ? $request->getParameter('lock_spec') : $user->lock_spec; $form = new Form('lockingForm'); -$form->addInput(array('type'=>'text','maxlength'=>'10','name'=>'lock_interval','value'=>$cl_lock_interval)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'lock_spec','style'=>'width: 250px;','value'=>$cl_lock_spec)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); if ($request->isPost()) { - if ($cl_lock_interval == null || trim($cl_lock_interval) == '') $cl_lock_interval = 0; + // Validate user input. + if (!ttValidCronSpec($cl_lock_spec)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.cron_schedule')); - if (ttTeamHelper::update($user->team_id, array( - 'name' => $user->team, - 'locktime' => $cl_lock_interval))) { - header('Location: time.php'); - exit(); - } else { - $err->add($i18n->getKey('error.db')); + if ($err->no()) { + if (ttTeamHelper::update($user->team_id, array( + 'name' => $user->team, + 'lock_spec' => $cl_lock_spec))) { + header('Location: time.php'); + exit(); + } else { + $err->add($i18n->getKey('error.db')); + } } } // isPost diff --git a/mysql.sql b/mysql.sql index e964ac72..5e669305 100644 --- a/mysql.sql +++ b/mysql.sql @@ -27,6 +27,8 @@ CREATE TABLE `tt_teams` ( `tracking_mode` smallint(2) NOT NULL DEFAULT '1', # tracking mode ("projects" or "projects and tasks") `record_type` smallint(2) NOT NULL DEFAULT '0', # time record type ("start and finish", "duration", or both) `plugins` varchar(255) default NULL, # a list of enabled plugins for team + `lock_spec` varchar(255) default NULL, # Cron specification for record locking, + # for example: "0 10 * * 1" for "weekly on Mon at 10:00". `custom_logo` tinyint(4) default '0', # whether to use a custom logo or not `status` tinyint(4) default '1', # team status PRIMARY KEY (`id`) -- 2.20.1
{$i18n.label.lock_interval}:{$forms.lockingForm.lock_interval.control}{$i18n.label.cron_schedule}:{$forms.lockingForm.lock_spec.control} {$i18n.label.what_is_it}